How to hide the axes but keep the grid? - matlab

If we have a figure
plot(x, y);
grid on;
We get something like this
But now, I wish to hide the axis, so I tried the commands below:
axis off
set(gca,'xtick',[])
set(gca,'ytick',[])
set(gca,'visible','off')
Together they successfully hid the axis, but the grid was also deleted!
set(gca, 'xticklabel', []) can hide the label, but not the axis.
So, how do I hide the axis, ticks and labels, leaving only the plot and grid?

You can set Xcolor and Ycolor to none so the axis won't be displayed:
%dummy data
x = [-5:.1:5];
y = normpdf(x,0,1);
plot(x, y);
%grid on
grid on;
%Set the axis color to none.
set(gca,'XColor','none','Ycolor','none')

I'm not sure I understood what you wanted to achieve, but if this is what you meant,
here's how to do it:
function [] = q57076281()
% Plot some data with a grid:
x = linspace(0,2*pi,100);
y = sin(x);
figure(); hP = plot(x,y); hAx = hP.Parent;
grid(hAx, 'on');
% Remove the box:
box(hAx, 'off');
% Hide the labels:
set(hAx, 'XTickLabel', [], 'YTickLabel', []);
% Hide the axes:
hXl = struct(hAx.XAxis).Axle; hXl.Visible = 'off';
hXl = struct(hAx.YAxis).Axle; hXl.Visible = 'off';
% Hide the ticks:
hAx.TickLength = [0,0];

Related

matlab plot with multiple colormaps

I want to create a plot with pcolor plot with an contour plot on top. Both with different colormaps - pcolor with "hot", the contour with "gray".
I newer Matlab version multiple colormaps are possible.
The code works, however both axis do not overlap, even if the axes positions are in sync.
%% prepare Data
Data2D = peaks(100);
Data2D = Data2D -min(Data2D(:));
Data2D = Data2D/max(Data2D(:)) * 100;
steps = 0:05:100;
xAxis = 1:size(Data2D,2);
yAxis = 1:size(Data2D,1);
figure(1); clf
ax1 = axes;
hold on;
% 3D flat plot
caxis([0 100]);
cmap = fliplr(jet(1000));
colormap(ax1, cmap(1:800,:));
hplot = pcolor(ax1, xAxis, yAxis, Data2D);
shading flat; % do not interpolate pixels
set(ax1,'XLim',[xAxis(1) xAxis(end)]);
set(ax1,'YLim',[yAxis(1) yAxis(end)]);
% colorbar
hcb = colorbar('location','EastOutside');
set(hcb, 'Ylim', [0 100]);
%% contour plot
ax2 = axes; linkaxes([ax1,ax2])
colormap(ax2, flipud(gray(1000)));
[C,hfigc] = contour(ax2, xAxis, yAxis, Data2D,steps);
% Hide the top axes
ax2.Visible = 'off';
ax2.XTick = [];
ax2.YTick = [];
set(hfigc, 'LineWidth',1.0);
hold off;
drawnow
If you didn't use ax2.Visible = 'off' you would probably see that the axes' positions are different, since the first axes are squashed to allow room for the colorbar which the second axes don't have.
TL;DR
You need to set the position properties to be equal
ax2.Position = ax1.Position
Demo
You can simulate this with a blank figure:
1.
% Create figure and first axes, which have a colorbar
figure(1)
ax1 = axes();
colorbar('location', 'eastoutside');
Output:
2.
% Add new axes
hold on;
ax2 = axes();
Output (notice the second axes fills the space of the first + colorbar):
3.
% Make the same, so that the second axes also allow for the colorbar
ax2.Position = ax1.Position;
Output (notice thicker numbers showing they are overlapping fully):

How do I plot more than two functions onto the same graph with very different ranges in Octave?

I can't find any info on how to do this on the Internet other than to use plotyy which only seems to work for two functions.
From Matlab documentation:
Use Right y-Axis for Two Data Sets
Plot three data sets using a graph with two y-axes. Plot one set of
data associated with the left y-axis. Plot two sets of data associated
with the right y-axis by using two-column matrices.
x = linspace(0,10);
y1 = 200*exp(-0.05*x).*sin(x);
y2 = 0.8*exp(-0.5*x).*sin(10*x);
y3 = 0.2*exp(-0.5*x).*sin(10*x);
plotyy(x,y1,[x',x'],[y2',y3']);
In my opinion, the way to do this that confers the most manual control is to create three overlapping axes with the plots you need, and only display the axis for the topmost one. You could even create 'empty' axes just so you they can serve as the only axis with defined 'limits' in the x and y axes.
Example:
ax1 = axes();
X1 = linspace(0,8*pi, 100); Y1 = sin(X1);
plot(X1, Y1, 'r', 'linewidth', 10);
ax2 = axes();
h = ezplot(#(x) x .* sin(x), [-100, 100]); set(h, 'color', 'w');
ax3 = axes();
image()
%% place them on top of each other by calling them in the order you want
axes(ax3); % bottommost
axes(ax1);
axes(ax2); % topmost
set(ax1, 'visible', 'off');
set(ax2, 'visible', 'off');
set(ax3, 'visible', 'on'); % this is the axes who's limits will show

Add non-existent entry to legend

I want to add an entry manually to a MATLAB legend. This legend can be pre-existent and contain other graphed elements' entries, but not necessarily.
I make a scatter plot, but instead of using e.g. scatter(x,y), I plot it using
for n = 1:numel(x)
text(x(n),y(n),num2str(n), ...
'HorizontalAlignment','center','color',[1 0 0])
end
This results in a scatter plot of numbers one through the number of elements in x (and y, because they are of the same size). I want to add a legend entry for these numbers.
I tried to add or edit the legend with
[h,icons,plots,s] = legend(___)
as described on the legend documentation page. I can't figure out how I can add a legend entry, without having to plot something (such as an actual scatter plot or regular plot). I want the usual line or marker symbol in the legend to be a number or character such as 'n', indicating the numbers in the graph. Is this possible and how would one achieve this?
EDIT by Erik
My answer goes below zelanix's answer, because mine is based on it.
Original answer
A fairly workable solution may be as follows:
x = rand(10, 1);
y = rand(10, 1);
figure;
text(x,y,num2str(transpose(1:numel(x))),'HorizontalAlignment','center')
% Create dummy legend entries, with white symbols.
hold on;
plot(0, 0, 'o', 'color', [1 1 1], 'visible', 'off');
plot(0, 0, 'o', 'color', [1 1 1], 'visible', 'off');
hold off;
% Create legend with placeholder entries.
[h_leg, icons] = legend('foo', 'bar');
% Create new (invisible) axes on top of the legend so that we can draw
% text on top.
ax2 = axes('position', get(h_leg, 'position'));
set(ax2, 'Color', 'none', 'Box', 'off')
set(ax2, 'xtick', [], 'ytick', []);
% Draw the numbers on the legend, positioned as per the original markers.
text(get(icons(4), 'XData'), get(icons(4), 'YData'), '1', 'HorizontalAlignment', 'center')
text(get(icons(6), 'XData'), get(icons(6), 'YData'), '2', 'HorizontalAlignment', 'center')
axes(ax1);
Output:
The trick to this is that the new axes are created in exactly the same place as the legend, and the coordinates of the elements of the icons are in normalised coordinates which can now be used inside the new axes directly. Of course you are now free to use whatever font size / colour / whatever you need.
The disadvantage is that this should only be called after your legend has been populated and positioned. Moving the legend, or adding entries will not update the custom markers.
Erik's answer
Based on zelanix's answer above. It is a work-in-progress answer, I am trying to make a quite flexible function of this. Currently, it's just a script that you'd need to adapt to your situation.
% plot some lines and some text numbers
f = figure;
plot([0 1],[0 1],[0 1],[1 0])
x = rand(25,1);
y = rand(25,1);
for n = 1:numel(x)
text(x(n),y(n),num2str(n), ...
'HorizontalAlignment','center','color',[1 0 0])
end
hold on
% scatter(x,y) % used to test the number positions
scatter(x,y,'Visible','off') % moves the legend location to best position
% create the dummy legend using some dummy plots
plot(0,0,'o','Visible','off')
[l,i] = legend('some line','some other line','some numbers','location','best');
l.Visible = 'off';
% create empty axes to mimick legend
oa = gca; % the original current axes handle
a = axes;
axis manual
a.Box = 'on';
a.XTick = [];
a.YTick = [];
% copy the legend's properties and contents to the new axes
a.Units = l.Units; % just in case
a.Position = l.Position;
i = copyobj(i,a);
% replace the marker with a red 'n'
s = findobj(i,'string','some numbers');
% m = findobj(i(i~=s),'-property','YData','marker','o');
m = findobj(i(i~=s),'-property','YData');
sy = s.Position(2);
if numel(m)>1
dy = abs(m(1).YData - sy);
for k = 2:numel(m)
h = m(k);
dy2 = abs(h.YData - sy);
if dy2<dy
kbest = k;
dy = dy2;
end
end
m = m(kbest);
end
m.Visible = 'off';
mx = m.XData;
text(mx,sy,'n','HorizontalAlignment','center','color',[1 0 0])
% reset current axes to main axes
f.CurrentAxes = oa;
The result:

Matlab: Fitting two x axis and a title in figure

I am having trouble getting my title to show when I have a figure with two x-axis.
The plot looks good and the axis scales are as I would like them to be but the second axis label and the title end up outside my figure.
How do I get the plot and axis to have the same size and change the size of the figure to include labels and title?
Here is a minimal example:
x1 = linspace(0, 5);
y11 = sin(x1);
y12 = cos(x1);
x2 = linspace(4, 12);
figure(1)
plot(x1, y11, 'r');
hold on
grid on
plot(x1, y12, 'k');
axis([0 5 -1 1.8]);
legend('sin(x)', 'cos(x)');
xlabel('x')
ylabel('y-label');
ax1 = gca;
ax1_pos = ax1.Position;
ax2 = axes('Position', ax1_pos,...
'XAxisLocation', 'top',...
'YAxisLocation', 'right',...
'Color', 'none');
ax2.YColor = 'w';
title('2:nd Harmonics');
line(x2,0,'Parent',ax2,'Color','k')
xlabel('n');
As a workaround you could pre-define the Position property (i.e. size) of the 1st axes before generating the plot so that the title appears correctly even if you add a 2nd axes. For example, right after the call to figure(1) add something like this:
ax1 = axes('Position',[0.11 0.11 0.75 0.75]);
Also, if you wish to print exponent values in the title you can use Latex formatting as follows:
title('2^{nd} Harmonics');
Here is the whole code with output:
clear
clc
close all
x1 = linspace(0, 5);
y11 = sin(x1);
y12 = cos(x1);
x2 = linspace(4, 12);
figure(1)
%// Set axes position manually
ax1 = axes('Position',[0.11 0.11 0.75 0.75]);
plot(x1, y11, 'r');
hold on
grid on
plot(x1, y12, 'k');
axis([0 5 -1 1.8]);
legend('sin(x)', 'cos(x)');
xlabel('x')
ylabel('y-label');
%ax1 = gca;
ax1_pos = get(ax1,'Position');
ax2 = axes('Position', ax1_pos,...
'XAxisLocation', 'top',...
'YAxisLocation', 'right',...
'Color', 'none');
set(ax2,'YColor','w');
%// Notice the Latex formatting to print the exponent
title('2^{nd} Harmonics');
line(x2,0,'Parent',ax2,'Color','k')
xlabel('n');
Then you can resize as you wish; the title stays visible.

Plot outside axis in Matlab

How to plot something outside the axis with MATLAB? I had like to plot something similar to this figure;
Thank you.
Here is one possible trick by using two axes:
%# plot data as usual
x = randn(1000,1);
[count bin] = hist(x,50);
figure, bar(bin,count,'hist')
hAx1 = gca;
%# create a second axis as copy of first (without its content),
%# reduce its size, and set limits accordingly
hAx2 = copyobj(hAx1,gcf);
set(hAx2, 'Position',get(hAx1,'Position').*[1 1 1 0.9], ...
'XLimMode','manual', 'YLimMode','manual', ...
'YLim',get(hAx1,'YLim').*[1 0.9])
delete(get(hAx2,'Children'))
%# hide first axis, and adjust Z-order
axis(hAx1,'off')
uistack(hAx1,'top')
%# add title and labels
title(hAx2,'Title')
xlabel(hAx2, 'Frequency'), ylabel(hAx2, 'Mag')
and here is the plot before and after:
You can display one axis with the scale you want, then plot your data on another axis which is invisible and large enough to hold the data you need:
f = figure;
% some fake data
x = 0:20;
y = 23-x;
a_max = 20;
b_max = 23;
a_height = .7;
%% axes you'll see
a = axes('Position', [.1 .1 .8 a_height]);
xlim([0 20]);
ylim([0 20]);
%% axes you'll use
scale = b_max/a_max;
a2 = axes('Position', [.1 .1 .8 scale*a_height]);
p = plot(x, y);
xlim([0 20]);
ylim([0 b_max]);
set(a2, 'Color', 'none', 'Visible', 'off');
I had similar problem and I've solved it thanks to this answer. In case of bar series the code is as follows:
[a,b] = hist(randn(1000,1)); % generate random data and histogram
h = bar(b,a); % plot bar series
ylim([0 70]) % set limits
set(get(h,'children'),'clipping','off')% turn off clippings