Hide Chart axes but show labels in Matlab - matlab

I want to hide the complete axes form a figure in Matlab.
However, I do want to show the xlabel.
Here's a workaround which worked at Matlab 2015a:
colormap(gray);
imagesc(-prog(:,:,fig));
xlabel(sprintf('c = %.2f',C(:,:,loop(fig))),'color','k')
axis equal; axis tight;
set(gca,'XTick',[],'YTick',[],'XTicklabel',[],...
'YTicklabel',[],'xcolor','w','ycolor','w')
However, since 2015b and 2016a this doesn't work anymore, the xlabels are not shown in white (instead of black)

You need to change the xlabel color after you change the XColor of the axes otherwise set(gca, 'XColor', 'w') forces everything to be white regardless of what you set it to previously.
figure(1)
C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
imagesc(C)
% Change axes colors and appearance
axis equal; axis tight;
set(gca,'XTick',[],'YTick',[],'XTicklabel',[],...
'YTicklabel',[],'xcolor','w','ycolor','w')
% NOW create your black xlabel
xlabel(sprintf('c = test'),'color','k')

Related

Single Colorbar for Vertical Subplots

I would like to make the following MATLAB plot have a single colorbar that extends along both subplots.
Something like this (done manually with the figure editor):
Note: This is different from the question asked here.
Thanks!
I finally figured out a solution. The colorbar can be manually positioned in code but I wanted to keep everything the original spacing. My final solution is outlined below.
Step 1. Create the plot with a single colorbar on the bottom subplot.
figure('color', 'white', 'DefaultAxesFontSize', fontSize, 'pos', posVec)
ax(1) = subplot2(2,1,1);
pcolor(x2d, t2d, dataMat1)
shading interp
ylim([0 10])
xlim([-0.3 0.3])
xticklabels({})
set(gca, 'clim', [-20 0])
colormap(flipud(gray))
set(gca,'layer','top')
axis ij
ax(2) = subplot2(2,1,2);
pcolor(x2d, t2d, dataMat2);
xlabel('x')
ylabel('y')
shading interp
ylim([0 10])
xlim([-0.3 0.3])
set(gca, 'clim', [-20 0])
yticklabels({})
cbar = colorbar;
cbar.Label.String = 'Normalized Unit';
colormap(flipud(gray))
set(gca,'layer','top')
axis ij
Step 2. Save the position vectors of the two subplots and the colorbar.
pos1 = ax(1).Position; % Position vector = [x y width height]
pos2 = ax(2).Position;
pos3 = cbar.Position;
Step 3. Update the position of the colorbar to extend to the top of the top subplot.
cbar.Position = [pos3(1:3) (pos1(2)-pos3(2))+pos1(4)];
Step 4. Update the width of the top subplot to accommodate the colorbar.
ax(1).Position = [pos1(1) pos1(2) pos2(3) pos1(4)];
Step 5. Update the width of the bottom subplot to accommodate the colorbar.
ax(2).Position = pos2;
Wait, I thought the bottom subplot already accommodated the colorbar? Actually, when setting the position of the colorbar manually (step 3), the corresponding axis no longer scales accordingly. From the documentation:
If you specify the Position property, then MATLAB changes the Location property to 'manual'. The associated axes does not resize to accommodate the colorbar when the Location property is 'manual'.
The final result:

Matlab - plot - How to get the x-axis labels in a color keeping the x-axis color black and the first tick value hidden?

How to get the xaxis labels 2 4 6 in blue keeping the x-axis color black and the first tick value hidden?
when I am trying to change the tick label color the tick labels disappear
x=0:0.25:5
y=sin(x)
ax1 = subplot(1,2,1) ;
plot(x,y)
set(gca, 'YAxisLocation', 'right')
xlabel('x','Color','b')
ylabel('y')
%set(gca,'xColor','k');
%set(gca,'xticklabel','b')
Q=get(gca,'xtick');
R=get(gca,'xticklabel');
set(gca,'xtick',Q(2:end))
set(gca,'xticklabel',R(2:end,:))
You can do this using the undocumented XRuler property of the axis:
h = gca;
h.XRuler.TickLabels.ColorData = uint8([0;0;255;255]);
Note this might not be available in older versions of MATLAB, it works for me on 2015a
Inspired by this answer, I decided to try and solve your problem in a similar manner. I was able to find a working solution, but it's not pretty as you need to copy several axes objects, and it seems that it's not robust to resizing of the figure. Hopefully it will still be helpful!
The code is below.
%//Original code
x=0:0.25:5;
y=sin(x);
ax1 = subplot(1,2,1);
plot(x,y)
set(ax1, 'YAxisLocation', 'right')
ylabel(ax1, 'y');
xlabel(ax1, 'x', 'Color', 'b'); %// Give the blue 'x' as label
%//Solution
my_xticks = [2 4 6]; %// The XTicks you want to show
drawnow; %//Must draw the axes here due to YAxisLocation, otherwise will not work
ax2 = copyobj(ax1, gcf); %// Create a copy the axes
set(ax2, 'XTick', my_xticks, 'XColor', 'b', 'Color', 'none') %// Keep only my_xticks in blue
ax3 = copyobj(ax1, gcf); %// Create another copy...
set(ax3, 'XTick', [], 'Color', 'none'); %// From which we keep only the black gridline
xlabel(ax3, ''); %// Remove the xlabel from ax3 (would show x in wrong position)
set(ax1, 'xtick', my_xticks); %// In ax1, show black ticks at desired locations
End result looks like this:
Caveats, as mentioned: You are copying the axes object twice, which is wasteful. If you resize the figure, the construction seems to implode. I could not figure out how to fix these.

Why is the actual value of an axis position different than the derived value in MATLAB suplot figure?

I've got a figure with two subplots being displayed. I want to get the axis position of each plot so I am using the figure's children information:
subplot(211)
% Plot stuff here
...
subplot(212)
% Plot stuff here
...
% Get Axes Position information
f =gcf;
% Bottom Plot Axis
disp(f.Children(2).Position)
% Top Plot Axis
disp(f.Children(4).Position)
The console displays:
Bottom plot:
0.1300 0.1100 0.7750 0.3412
Top plot:
0.1300 0.5838 0.7750 0.3412
This seems correct given all else. When I run the plot to generate the figure and then inspect the axes' information via 'Show Plot Tools and Dock Figure->Inspector: matlab.graphics.axis.Axes' option the width value for each axis's position is not 0.7750. The other position values are as listed but the width is different for both the top and bottom plots. The top becomes [0.13 0.5838 0.682 0.341] and the bottom becomes [0.13 0.11 0.67 0.341].
Does anyone know why this is and how to get the "real" position values and not the incorrect displayed/printed ones?
Useful info: MATLAB R2014b
EDIT UPDATE:
Here is a MWE that produces the behavior.
clear all; close all; clc;
figure;
subplot(211)
hold on
x1 = [ -1 -0.998 -0.996 -0.994 -0.992];
y = [0.000324249267578125 -0.000370025634765625 -3.4332275390625e-005 -0.000186920166015625 -0.000110626220703125];
plot(x1, y, '-', 'MarkerSize', 10)
set(gca, 'FontName', 'Interstate-Light', 'FontSize', 7)
set(gca, 'XTickLabel', [])
set(gca, 'XLabel', [])
grid on
ylabel('Frequency Error (Hz)', 'FontName', 'Interstate-Bold')
legend({'FE'}, 'Location', 'NorthEastOutside', 'FontName', 'Interstate-Light', 'Box', 'off')
subplot(212)
hold on
x1 = [ -1 -0.998 -0.996 -0.994 -0.992];
y = [-0.010614013299346 -0.0417663566768169 0.0235949698835611 -0.0502893067896366 0.0316442884504795];
plot(x1, y, '-', 'MarkerSize', 10)
% Overide X-axis ticks to align with data
XTick = unique(x1);
grid on;
xlabel('Time (s)', 'FontName', 'Interstate-Bold')
ylabel('Frequency Error (Hz)', 'FontName', 'Interstate-Bold')
set(gca, 'FontName', 'Interstate-Light', 'FontSize', 7)
legend({'RFE'}, 'Location', 'NorthEastOutside', 'FontName', 'Interstate-Light', 'Box', 'off')
% Get figure object
f = gcf;
% Set fontsize to 16 for readability in final pdf
set(findall(f, '-property','FontSize'),'FontSize',16)
f.PaperUnits = 'inches';
f.PaperPosition = [0 0 20 14];
f.PaperPositionMode = 'manual';
% Get axis position info
disp('Second plot:')
disp(f.Children(2).Position)
disp('First Plot:')
disp(f.Children(4).Position)
I'm working with R2012b and I've been able to reproduce the problem and also (almost) been able to understand what's happening.
I do not know if it is also applicable to more "recent" versin of MatLab.
The problem seems related to the default configuration of the window Show Plot Tools and Dock Figure
With this configuration, actually the position of the two axes (read in the Property editor are different with respect to the "original ones:
original pos ax 1= [0.1300 0.5838 0.7750 0.3412]
new pos ax1=[0.1300 0.629 0.7750 0.268 ]
Nevertheless, if you minimize the Property editor tab and look at the Position of the two axes, they are restored to the "original" one values.
You can, the "slide up" the tab and the position still remain the "original onne.
I'do not know if this is actually an answer to you question; what I can say is that the right position position are the "original" ones.
It could be a sort of bug in the visualization in the default configuratin od the Show Plot Tools and Dock Figure window.
Hope this helps.

Minor grid with solid lines & grey-color

I'm using the following to display the minor grid in my plot:
grid(gca,'minor')
set(gca,'MinorGridLineStyle','-')
but I'd like to change the color of the grid lines to a nice greyscale. I can't find any option 'grid color' in matlab... Do you know any or any workaround?
I found this: http://www.mathworks.com/matlabcentral/fileexchange/9815-gridcolor but as I read of the comments, it doesn't work very well and further it only changes gridcolor, not the color of the minor grid...
Thanks!
EDIT:
Problem with semilogx as posting here now:
x = [1e-9 1e-8 1e-7 1e-6 1e-5 1e-4 1e-3 1e-2]';
y1 = linspace(20, 90, 8);
y2 = y1.^2;
y3 = y1./y2+5;
% plotte: http://www.mathworks.com/help/techdoc/ref/linespec.html
myfig = figure('Position', [500 500 445 356]); %[left, bottom, width, height]:
p1 = semilogx(x,y1,'x--r',x,y2,'*-b');
ax1 = gca;
set(ax1, 'Position',[0.13 0.18 0.75 0.75]);
xlim([0 max(x)]);
ylim([0 max([max(y1) max(y2)])]);
col=.85*[1 1 1];
%# create a second transparent axis, same position/extents, same ticks and labels
ax2 = axes('Position',get(ax1,'Position'), ...
'Color','none', 'Box','on', ...
'XTickLabel',get(ax1,'XTickLabel'), 'YTickLabel',get(ax1,'YTickLabel'), ...
'XTick',get(ax1,'XTick'), 'YTick',get(ax1,'YTick'), ...
'XLim',get(ax1,'XLim'), 'YLim',get(ax1,'YLim'),...
'XScale', 'log');
%# show grid-lines of first axis, give them desired color, but hide text labels
set(ax1, 'XColor',col, 'YColor',col, ...
'XMinorGrid','on', 'YMinorGrid','on', ...
'MinorGridLineStyle','-', ...
'XTickLabel',[], 'YTickLabel',[],'XScale', 'log');
%# link the two axes to share the same limits on pan/zoom
linkaxes([ax1 ax2],'xy');
Displaying like this:
EDIT2: A problem occurs when adding a second y-axes as in the following picture, look at the ticks of the right y-axes:
this will be discussed here to have a better overview!
Matlab: Problem with ticks when setting minor grid style and two y-axis
Set the 'XColor','YColor' axes properties. Note that these properties determine the color of the axis lines, tick marks, tick mark labels, and the axis grid lines, so AFAIK you can't assign those different colors than that of the entire axis..
Example:
plot(rand(10,1))
set(gca, 'XMinorGrid','on', 'YMinorGrid','on', 'XColor','r', 'YColor','g')
EDIT1:
You can always create a second transparent axis with the desired grid colors, but with no ticks or labels, stacked on top of the current axis. Here is an example:
%# create plot as usual
plot(rand(10,1))
hAx1 = gca;
%# create a second axis, same position/extents, no tick or labels, colored grid-lines
hAx2 = axes('Position',get(hAx1,'Position'), ...
'Color','none', 'TickLength',[1e-100 1e-100], ...
'XMinorGrid','on', 'YMinorGrid','on', ...
'Box','off', 'XColor','g', 'YColor','r', ...
'XTickLabel',[], 'YTickLabel',[], ...
'XTick',get(hAx1,'XTick'), 'YTick',get(hAx1,'YTick'), ...
'XLim',get(hAx1,'XLim'), 'YLim',get(hAx1,'YLim'));
%# position it on top
%#uistack(hAx2,'top')
%# redraw the enclosing box in the original axis colors
x = get(hAx1,'XLim');
y = get(hAx1,'YLim');
line([x([1 2]) nan x([2 1])],[y([1 1]) nan y([2 2])],'Color',get(hAx1,'XColor'))
line([x([1 1]) nan x([2 2])],[y([1 2]) nan y([2 1])],'Color',get(hAx1,'YColor'))
The only problem is that the grid lines are drawn on top of your plot, which might get in the way if the grid-lines are thick :)
EDIT2:
Seems like #yoda had a similar idea to the above. Here is a slightly improved version inspired by his solution:
%# create plot as usual
plot(11:20, rand(10,1)*5)
hAx1 = gca; %# get a handle to first axis
%# create a second transparent axis, same position/extents, same ticks and labels
hAx2 = axes('Position',get(hAx1,'Position'), ...
'Color','none', 'Box','on', ...
'XTickLabel',get(hAx1,'XTickLabel'), 'YTickLabel',get(hAx1,'YTickLabel'), ...
'XTick',get(hAx1,'XTick'), 'YTick',get(hAx1,'YTick'), ...
'XLim',get(hAx1,'XLim'), 'YLim',get(hAx1,'YLim'));
%# show grid-lines of first axis, give them desired color, but hide text labels
set(hAx1, 'XColor','g', 'YColor','r', ...
'XMinorGrid','on', 'YMinorGrid','on', ...
'XTickLabel',[], 'YTickLabel',[]);
%# link the two axes to share the same limits on pan/zoom
linkaxes([hAx1 hAx2],'xy');
%# lets create a legend, and some titles
legend(hAx1, 'text')
title('title'), xlabel('x'), ylabel('y')
EDIT3 (take 2):
Here is the same example but with a log-scale x-axis. Note how instead of creating a second axis and manually setting its properties to match the first, I simply copyobj the axis, and delete its children.
%# create a plot as usual (x-axis is in the log-scale)
semilogx(logspace(0,5,100), cumsum(rand(100,1)-0.5))
xlabel('x'), ylabel('y'), title('text')
legend('plot')
%# capture handle to current figure and axis
hFig = gcf;
hAx1 = gca;
%# create a second transparent axis, as a copy of the first
hAx2 = copyobj(hAx1,hFig);
delete( get(hAx2,'Children') )
set(hAx2, 'Color','none', 'Box','on', ...
'XGrid','off', 'YGrid','off')
%# show grid-lines of first axis, style them as desired,
%# but hide its tick marks and axis labels
set(hAx1, 'XColor',[0.9 0.9 0.9], 'YColor',[0.9 0.9 0.9], ...
'XMinorGrid','on', 'YMinorGrid','on', 'MinorGridLineStyle','-', ...
'XTickLabel',[], 'YTickLabel',[]);
xlabel(hAx1, ''), ylabel(hAx1, ''), title(hAx1, '')
%# link the two axes to share the same limits on pan/zoom
linkaxes([hAx1 hAx2], 'xy');
%# Note that `gca==hAx1` from this point on...
%# If you want to change the axis labels, explicitly use hAx2 as parameter.
You should get the correct plot in your example with this code. However I think the x variable values you choose might be too close in the current figure size to show all the vertical lines (simply maximize the figure to see what I mean)...
To get a better idea of what each axis contains, here is a divided view where the plot on the left contains only the graphics rendered by hAx1, while the plot on right contains only the hAx2 components. Those two views are basically overlayed on top of each other in the final figure shown before.
Unfortunately, while the trick of over- or under-laying a second, gridded axes mostly works, Matlab does not render it properly when you save to a PDF file. This is because Matlab does not support transparency in PDFs.
One workaround is to simply use line to draw in the grid lines one by one:
for dir='XY';
ticks = get(gca, [dir 'Tick']);
lim = get(gca, [dir 'lim']);
for ii=1:length(ticks)
coord = ticks(ii);
for jj=1:9,
if jj==1 % major grid properties
color = [1 1 1]*0.9;
weight = 2;
else % minor grid properties
color = [1 1 1]*0.9;
weight = 1;
end
if jj*coord > lim(2)
continue
end
if dir=='X'
L = line((jj*coord)*[1 1], get(gca, 'ylim'), ...
'color', color, 'linewidth', weight);
else
L = line(get(gca, 'xlim'), (jj*coord)*[1 1], ...
'color', color, 'linewidth', weight);
end
uistack(L, 'bottom');
end
end
end
One downside of this approach is that it overwrites the tick marks and plot boundary box. A solution to this is to combine this approach with the trick of under-laying a second axes. Draw the fake grid on the underlying axes. This IS rendered properly in PDF:
While Amro is right that the minor grid's color is the same as that of the axis labels, you can always turn off the axis labels and overlay a second axes with transparent filling and set the labels on that in a different color. Here's a small example showing how:
plot(rand(10,1))
xTicks=get(gca,'xTick');
yTicks=get(gca,'ytick');
set(gca, 'XMinorGrid','on', 'YMinorGrid','on',...
'XColor','r', 'YColor','g','xticklabel',[],'yticklabel',[],...
'box','off')
h2=axes;
set(h2,'color','none','xtick',linspace(0,1,numel(xTicks)),'xticklabel',xTicks,...
'ytick',linspace(0,1,numel(yTicks)),'yticklabel',yTicks)
This lets you set independent colors for major and minor X and Y grid lines, without overwriting the outer box. Even better, subsequent legend() commands will pick up the plot lines, not the manually drawn grid lines.
The trick is to make copies of the axes, then reverse their order in the figure's drawing hierarchy. Each copy of the axes can then draw its own set of grid colors and styles.
This strategy is compatible with subplot() and print().
function gridcolor(majorX, majorY, minorX, minorY)
ax1 = gca; %# get a handle to first axis
%# create a second transparent axis, same position/extents, same ticks and labels
ax2 = copyobj(ax1,gcf);
ax3 = copyobj(ax1,gcf);
delete(get(ax2,'Children'));
delete(get(ax3,'Children'));
set(ax2, 'Color','none', 'Box','off','YTickLabel',[],'YTickLabel',[],...
'GridLineStyle', '-',...
'XGrid','on','YGrid','on',...
'XMinorGrid','off','YMinorGrid','off',...
'XColor',majorX,'YColor',majorY);
set(ax3,'Box','off','YTickLabel',[],'YTickLabel',[],...
'MinorGridLineStyle','-',...
'XGrid','off','YGrid','off',...
'XMinorGrid','on','YMinorGrid','on',...
'XColor',minorX,'YColor',minorY);
set(ax1, 'Color','none', 'Box','on')
handles = [ax3; ax2; ax1];
c = get(gcf,'Children');
for i=1:length(handles)
c = c(find(c ~= handles(i)));
end
set(gcf,'Children',[c; flipud(handles)]);
linkaxes([ax1 ax2 ax3]);
end
subplot(211);semilogx([1:4000]);gridcolor('r','g','c','b');
subplot(212);semilogx(([1:4000]).^-1);gridcolor('r','g','c','b');

How to control the margin size around subplots?

I'm plotting 5 x 3 plots using subplot command, but there are massive margins around each subplot.
How do I control the margin size around them?
figure;
for c=1:15
subplot(5,3,c);
imagesc(reshape(image(:,c), 360,480));
colormap gray;
axis image;
end
The problem is that Matlab assigns the position property of each axis such that there is space around each plot. You can either adjust the position property, or you can get subaxis from the File Exchange and set up the subplots the way you like.
Take a look at the axes's LooseInset and OuterPosition properties:
http://undocumentedmatlab.com/blog/axes-looseinset-property/
Since MATLAB R2019b you can use tiledlayout function to control the spacing of the subplots.
Here's an example which shows how to obtain subplots without tile spacing:
figure
example_image = imread('cameraman.tif');
t = tiledlayout(5,3);
nexttile
for c= 1:15
imagesc(example_image(:,c))
if c < 15
nexttile
end
end
t.TileSpacing = 'None';
In addition to the other answers, you could try Chad Greene's smplot from the FileExchange. This will produce a 'small multiple' plot and automatically deal with some of the hassle of Matlab's position property.
Example below showing default subplot behaviour, smplot with axis off and smplot with axis on, respectively:
image = randn(360*480,15);
% default subplot
figure;
for c=1:15
subplot(5,3,c);
imagesc(reshape(image(:,c), 360,480));
colormap gray;
axis image;
end
% smplot axis off
figure;
for c=1:15
smplot(5,3,c);
imagesc(reshape(image(:,c), 360,480));
colormap gray;
axis off;
end
% smplot axis on
figure;
for c=1:15
smplot(5,3,c,'axis','on');
imagesc(reshape(image(:,c), 360,480));
colormap gray;
axis tight;
end
To minimize the white space surrounding each subplot, run: [1]
for c=1:15
h_ax = subplot(5,3,c);
% [...]
outerpos = get(h_ax,'OuterPosition');
ti = get(h_ax,'TightInset');
left = outerpos(1) + ti(1);
bottom = outerpos(2) + ti(2);
ax_width = outerpos(3) - ti(1) - ti(3);
ax_height = outerpos(4) - ti(2) - ti(4);
set(h_ax,'Position',[left bottom ax_width ax_height]);
end
This implementation automates the principle outlined in Jonas's answer.
[1] https://www.mathworks.com/help/releases/R2015b/matlab/creating_plots/save-figure-with-minimal-white-space.html