Draw vertical line on histogram plot matlab - matlab

Matlab R2015b. I used the following code to draw the histogram:
close all;
hold on;
ko = histograms_windows_1_0{7};
histogram(ko);
set(gca,'XLim',[0 30],'XTick',0:5:30);
xticks = [0;0.16;0.33;0.5;0.66;0.83;1];
set(gca,'XTickLabel', xticks)
xlabel('Seconds');
ylabel('Correct Transitions');
That gives me the picture:
Now I want to add vertical line showing mean value by the "seconds" axis, I already know that value and also the standard deviation. Something similar to:
I have mn and stdv values. I've tried this:
mn = mean(ko) / 30;
stdv = std(ko) / 30;
hax=axes;
line([mn mn],get(hax,'YLim'))
hold off;
But it ignores previously drawn histogram and draws vertical line but only that line is shown, no histogram anymore. How that can be achieved?

The problem is the line
hax=axes;
This creates a new axis object which covers the previous one.
The solution is to change into
hax=gca;
so that the subsequent line goes to the same axis that contains the histogram.

Related

Remove border around axes but keep the grid and ticklabels [duplicate]

Is there a way to remove only the axis lines in the Matlab figure, without affecting ticks and tick labels.
I know that box toggles the upper and right axes lines and ticks and that works perfectly for me.
But my problem is that I want eliminate the bottom and left lines (only lines!) but keeping the ticks and tick labels.
Any tricks?
Yair Altman's Undocumented Matlab demonstrates a cleaner way to do this using the undocumented axes rulers:
plot(x,y);
ax1 = gca;
yruler = ax1.YRuler;
yruler.Axle.Visible = 'off';
xruler = ax1.XRuler;
xruler.Axle.Visible = 'off'; %// note you can do different formatting too such as xruler.Axle.LineWidth = 1.5;
A nice feature of this approach is that you can separately format the x and y axis lines.
Solution for Matlab versions prior to R2014b
You can introduce a new white bounding box and put it on top.
// example data
x = linspace(-4,4,100);
y = 16 - x.^2;
plot(x,y); hold on
ax1 = gca;
set(ax1,'box','off') %// here you can basically decide whether you like ticks on
%// top and on the right side or not
%// new white bounding box on top
ax2 = axes('Position', get(ax1, 'Position'),'Color','none');
set(ax2,'XTick',[],'YTick',[],'XColor','w','YColor','w','box','on','layer','top')
%// you can plot more afterwards and it doesn't effect the white box.
plot(ax1,x,-y); hold on
ylim(ax1,[-30,30])
Important is to deactivate the ticks of the second axes, to keep the ticks of the f rist one.
In Luis Mendo's solution, the plotted lines are fixed and stay at their initial position if you change the axes properties afterwards. That won't happen here, they get adjusted to the new limits. Use the correct handle for every command and there won't be much problems.
Dan's solution is easier, but does not apply for Matlab versions before R2014b.
There is another undocumented way (applicable to MATLAB R2014b and later versions) of removing the lines by changing the 'LineStyle' of rulers to 'none'.
Example:
figure;
plot(1:4,'o-'); %Plotting some data
pause(0.1); %Just to make sure that the plot is made before the next step
hAxes = gca; %Axis handle
%Changing 'LineStyle' to 'none'
hAxes.XRuler.Axle.LineStyle = 'none';
hAxes.YRuler.Axle.LineStyle = 'none';
%Default 'LineStyle': 'solid', Other possibilities: 'dashed', 'dotted', 'dashdot'
This is different from Dan's answer which uses the 'visible' property of rulers.
You could "erase" the axis lines by plotting a white line over them:
plot(1:4,1:4) %// example plot
box off %// remove outer border
hold on
a = axis; %// get axis size
plot([a(1) a(2)],[a(3) a(3)],'w'); %// plot white line over x axis
plot([a(1) a(1)],[a(3) a(4)],'w'); %// plot white line over y axis
Result:
As noted by #SardarUsama, in recent Matlab versions you may need to adjust the line width to cover the axes:
plot(1:4,1:4) %// example plot
box off %// remove outer border
hold on
a = axis; %// get axis size
plot([a(1) a(2)],[a(3) a(3)],'w', 'linewidth', 1.5); %// plot white line over x axis.
%// Set width manually
plot([a(1) a(1)],[a(3) a(4)],'w', 'linewidth', 1.5);

Histogram with a mean line in same spot

I'm using Matlab and have created a histogram and want a vertical line to indicate the mean. So far my code is
N=100;
mydata=rand(N,1);
mymean=mean(mydata);
histogram(mydata);
figure(1)
hold on
line(mymean,N,'r')
I expect to find a red line crossing the x-axis at the mean value, but there is no line plotted. What is wrong here?
I assume you want your line to go from the point p1=[mymean 0] to the point p2=[mymean N]. Just tell that to the line function. Right now you are drawing a line that only goes to a point, so it is that, a point.
line([mymean mymean],[0 N],'r')
But I see no reason to use line as it is just a low level function of plot, so just do
plot([mymean mymean],[0 N],'r')
Starting in the 2018b version, xline() draws a vertical line.
N = 100;
mydata = rand(N,1);
mymean = mean(mydata);
h = histogram(mydata);
h2 = xline(mymean,'r-','LineWidth',1.5); % Requires MATLAB R2018b or later
Other LineStyles are available: '-', '--', ':', '-.'.
h2.LineStyle = '--';
Color is also easily changed.
For more info, see How to draw horizontal and vertical lines in MATLAB?, especially this answer.

How to draw differently spaced grid lines in Matlab

On mathworks, I have found a code which is suppossed to draw grid lines in a plot:
g_x = -25:1.25:0;
g_y = -35:2.5:-5;
for i = 1:length(g_x)
plot([g_x(i) g_x(i)],[g_y(1) g_y(end)],'k:')% y grid lines
hold on
end
for i=1:length(g_y)
plot([g_x(1) g_x(end)],[g_y(i) g_y(i)],'k:') % x grid lines
hold on
end
here's a link
I don't understand the plot command: e.g. the y grid lines - one of the inputs is a vector containing all the spacing points of the x-axis, where I want to have a grid. These points are given in two columns and they are assigned to the second vector, which only contains the first and the last point shown on the y-axis. As I understand this command, it will for example take the first element g_x(1) and g_y(1) and plot a : , it will then take g_x(2) and g_y(1) and plot :, and so on. But How does it keep on plotting : from g_y(1) continuously until g-y(end) ?
To directly answer your question, it simply plots the two endpoints of each grid line and since the default LineStyle used by plot is a solid line, they will automatically be connected. What that code is doing is creating all permutations of endpoints and plotting those to form the grid.
Rather than creating custom plot objects (if you're using R2015b or later), you can simply use the minor grid lines and modify the locations of the minor tick marks of the axes.
g_x = -25:1.25:0;
g_y = -35:2.5:-5;
ax = axes('xlim', [-25 0], 'ylim', [-35 -5]);
% Turn on the minor grid lines
grid(ax, 'minor')
% Modify the location of the x and y minor tick marks
ax.XAxis.MinorTickValues = g_x;
ax.YAxis.MinorTickValues = g_y;
Basically the code does this:
g_x = -25:1.25:0;
generates a array with values -25.0000 -23.7500 -22.5000 -21.2500 ... 0
These are the positions where vertical lines are drawn
The same holds for g_y, but of course this determines where horizontal lines are drawn.
The option 'k' determined that it is a dashed line.
And the loops just loo through the arrays.
So in the first iteration the plot function draws a line from the position
[-25, -35]
to the position
[-25, -5]
So if you want to change the grid, just change the values stored in g_x
g_x = -25:3.0:0;
would for example draw vertical lines with the width 3.0
I hope this makes sense for you.

How do I plot a horizontal line and a curve in the same graph in MATLAB?

I'm supposed to show the plot of data (curve) and a plot of the average of the data (flat horizontal line) in the same graph. My code computes everything fine and displays the curve in the graph, but I can't get the horizontal line to show up.
plot(1:24,hours3,'b-.',1:24, avg3,'r--');
So the plot of the column "hours3" shows up just fine, but the plot of the average "avg3" does not come up at all. It should be a flat line that extends from points 1 to 24 on the x-axis. Does anyone know why this is?
It's because plot(1:24,avg3,rx--) is interpreted as 24 single points. Using rx-- as linestyle shows you that the points are plotted right but not connected.
plot(1:24,hours3,'b-.',1:24, repmat(avg3,1,24),'r--');
Also with hold on you can keep plotting in an existing figure.
Try below code:
StartPoint=1;
EndPoint=24;
Resolution=1; % you can set 0.1 if you want more precision
Ave=Ave3;% set a value for Ave3
x=[StartPoint:Resolution:EndPoint];
NumberofPoints=((EndPoint-StartPoint)/Resolution)+1;
HrzLine=Ave*ones(1,NumberofPoints);
Curve=0.2*x.^3-4.*x.^2+8;
plot(x,HrzLine);
hold on;
plot(x,Curve);
The 2018b release has made adding horizontal lines (& vertical lines) much easier with yline() (xline() for verticle lines).
Xrng = 1:.01:24;
fh =#(x) 0.2*x.^3 - 4.*x.^2 + 50*sin(x)+ 8; % curve
plot(Xrng,fh(Xrng))
yline(0) % horizontal line at y = 0
Subsequent lines can be added just as easily.
yline(50) % horizontal line at y = 0
xline(12,'b--') % vertical line at x = 12 (blue, dashed)
Requires MATLAB R2018b or later.

Moving MATLAB axis ticks by a half step

I'm trying to position MATLAB's ticks to line up with my grid, but I can't find a good way to offset the labels.
Also, if I run set(gca,'XTickLabel',1:10), my x tick labels end up ranging from 1 to 5. What gives?
You need to move the ticks, but get the labels before and write them back after moving:
f = figure(1)
X = randi(10,10,10);
surf(X)
view(0,90)
ax = gca;
XTick = get(ax, 'XTick')
XTickLabel = get(ax, 'XTickLabel')
set(ax,'XTick',XTick+0.5)
set(ax,'XTickLabel',XTickLabel)
YTick = get(ax, 'YTick')
YTickLabel = get(ax, 'YTickLabel')
set(ax,'YTick',YTick+0.5)
set(ax,'YTickLabel',YTickLabel)
Or if you know everything before, do it manually from the beginning:
[N,M] = size(X)
set(ax,'XTick',0.5+1:N)
set(ax,'XTickLabel',1:N)
set(ax,'YTick',0.5+1:M)
set(ax,'YTickLabel',1:M)
The marked answer works with a surf or mesh plot, however, I needed a solution which worked for a 2d plot.
This can be done by creating two axes, one to display the grid and the other to display the labels as follows
xlabels=1:1:10; %define where we want to see the labels
xgrid=0.5:1:10.5; %define where we want to see the grid
plot(xlabels,xlabels.^2); %plot a parabola as an example
set(gca,'xlim',[min(xgrid) max(xgrid)]); %set axis limits so we can see all the grid lines
set(gca,'XTickLabel',xlabels); %print the labels on this axis
axis2=copyobj(gca,gcf); %make an identical copy of the current axis and add it to the current figure
set(axis2,'Color','none'); %make the new axis transparent so we can see the plot
set(axis2,'xtick',xgrid,'XTickLabel',''); %set the tick marks to the grid, turning off labels
grid(axis2,'on'); %turn on the grid
This script displays the following figure :