How can I plot a Quarter graph in matlab? - matlab

I wanna to plot a graph as the below:
And this one:
I was doing something like this:
cc=hsv(ns);
hold on;
for nk=1:ns
figure(4); hold on;
h=plot(M1(nk,:),':','color',cc(nk,:));
set(h,'linewidth',2)
end
How can I do it?

For the first plot you just need to use plot and text plus some tweaking. If you want the legend in two columns, have a look at columnlegend in the Matlab File Exchange.
% generate some data
days = (1:250);
M1 = (days'*[0.06,-0.03,0.02,-0.04,0.05,-0.05,0.01])';
M1 = M1 + 0.5*randn(size(M1));
years = 2002+(1:size(M1,1));
ns = size(M1,1);
% prepare plot
figure(4); hold on;
cc = hsv(ns);
% plot all prices
for nk = 1:ns
ph = plot(days,M1(nk,:),'Color',cc(nk,:));
set(ph,'LineWidth',2);
end
% plot texts
for i = 1:4
h = text(250/8+(i-1)*250/4,18,['Q',num2str(i)]);
set(h,'FontSize',13,'HorizontalAlignment','center');
end
% plot vertical lines and the horizontal line
plot([250,250]'*(0:4)/4,[-21,21],'k-.');
plot([-10,250+10],[0,0],'k-.');
% set limits
set(gca,'XLim',[-10,250+10]);
set(gca,'YLim',[-21,21]);
% set labels and legend
xlabel('Day of Trading');
ylabel('Normalized Price');
lh = legend(cellstr(num2str(years')),'Location','SouthWest');
set(lh,'FontSize',8);
% tweak appearance
set(gca,'YTick',-20:10:20);
set(gca,'FontSize',13);
set(gca,'GridLineStyle',':');
grid on;
box on;
This is the result:
The second plot is very similar to the first one. For the confidence interval you can use fill. Because the entries in the legend have a different order as the order of plotting them, we store the handles and give it as the first argument to legend.
% generate some data
rng(2);
days = (1:250);
realised_Q1 = (1:62)*0.04+0.5*randn(1,62);
realised_Q234 = realised_Q1(end)+(1:189)*0.03+0.5*randn(1,189);
forecast_Q234 = realised_Q1(end)-3*sin((1:189)/40);
confidence_up = forecast_Q234+(1-exp(-(0:188)/10));
confidence_down = forecast_Q234-(1-exp(-(0:188)/10));
% prepare plot
figure; hold on;
ph = zeros(4,1);
% plot confidence interval
ph(4) = fill([days(62:250),fliplr(days(62:250))],...
[confidence_up,fliplr(confidence_down)],...
[0.85,0.85,1],'EdgeColor','none');
% plot realized Q1
ph(1) = plot(days(1:62),realised_Q1,'r','LineWidth',2);
% plot realized Q2 Q3 Q4 and forecast Q2 Q3 Q4
ph(2) = plot(days(62:250),realised_Q234,'k','LineWidth',2);
ph(3) = plot(days(62:250),forecast_Q234,'b','LineWidth',2);
% plot texts
for i = 1:4
h = text(250/8+(i-1)*250/4,13,['Q',num2str(i)]);
set(h,'FontSize',13,'HorizontalAlignment','center');
end
% plot vertical lines and the horizontal line
plot([250,250]'*(0:4)/4,[-21,21],'k-.');
plot([-10,250+10],[0,0],'k-.');
% set limits
set(gca,'XLim',[-10,250+10]);
set(gca,'YLim',[-6,16]);
% set labels and legend
xlabel('Day of Trading');
ylabel('Normalized Price');
lh = legend(ph,'Realized Q1 (2011)','Realized Q2 Q3 Q4 (2011)',...
'Forecast Q2 Q3 Q4 (2011)','Confidence',...
'Location','SouthWest');
set(lh,'FontSize',8);
% tweak appearance
set(gca,'YTick',-5:5:15);
set(gca,'FontSize',13);
set(gca,'GridLineStyle',':');
grid on;
box on;
This is the result:

Related

Removing a trend on a gravity curve MATLAB geophysics

any help would be appreciated
I am trying to remove the trend from my data, and the y axis curve should become negative, but this is not happening. Here is my code:
%% Line 1 Plot
filename = 'gravline1.xlsx';
X = readtable(filename);
x1 = X.Var1;
y1 = X.Var2;
g01 = X.Var3;
% fit a line through the data
P=polyfit(x1,g01,1) ;
fprintf('%10.6e\n',P(1));
% correct each point
for i=1:length(g01)
BA_C(i) = g01(i) - ((x1(i)-x1(1)).*P(1)) ;
end
% plot the corrected data
figure
plot(x1,BA_C,'ko','MarkerFaceColor','k','MarkerSize',4)
ylabel('Gravity BA (mgal)')
xlabel('Distance (m)')
title('Line 1 Trend Removed data ')

create bins based on a range of values for histogram figure

I am doing some analysis and need to produce a histogram plot. I know how to create the standard histogram plot but I need something like the image below, where each point is an interval on the x axis. Each bin is based on a value from x-x for example.
You can use the histogram function, and then set the XTick positions and XTickLabels accordingly. See the comments in the code for explanation.
% random normally distrubuted data
x = 1*randn(1000,1);
edges = -5:1:5;
% create vector with labels (for XTickLabel ... to ...)
labels = [edges(1:end-1); edges(2:end)];
labels = labels(:);
% plot the histogram
figure();
ax = axes;
h = histogram(x, 'BinEdges', edges, 'Normalization', 'Probability');
ax.XTick = edges + mean(diff(edges)/2);
ax.XTickLabel = sprintf('%.1f to %.1f\n', labels);
ax.XTickLabelRotation = 90;
% set yticks to percentage
ax.YTickLabel = cellfun(#(a) sprintf('%i%%', (str2double(a)*100)), ax.YTickLabel, 'UniformOutput', false);
% text above bars
bin_props = h.BinCounts/numel(x); % determine probabilities per bin in axis units
bin_centers = ax.XTick(1:end-1); % get the bin centers
txt_heigts = bin_props + 0.01; % put the text slightly above the bar
txt_labels = split(sprintf('%.1f%% ', bin_props*100), ' ');
txt_labels(end) = []; % remove last cell, is empty because of split.
text(ax, bin_centers, txt_heigts, txt_labels, 'HorizontalAlignment', 'center')
% set ylim to fit all text (otherwise text is outside axes)
ylim([0 .4]);
Putting the text at the right location may require some tweaking. Most important is the 'HorizontalAlignment' option, and the distance to the bars. I also used the 'Normalization', 'probability' option from the histogram function, and set the y axis to also show percentages.
I figure you can make the addition below yourself when needed.
When your data can be outside of the defined binedges, you can clip your data, and set the XTickLabels with less than or greater than signs.
% when data can be outside of defined edges
x = 5*randn(1000,1);
xclip = x;
xclip(x >= max(edges)) = max(edges);
xclip(x <= min(edges)) = min(edges);
% plot the histogram
figure();
ax = axes;
h = histogram(xclip, 'BinEdges', edges);
ax.XTick = edges + mean(diff(edges)/2);
ax.XTickLabel = sprintf('%.1f to %.1f\n', labels);
ax.XTickLabelRotation = 90;
% set boundary labels
ax.XTickLabel{1} = sprintf('\\leq %.1f', edges(2));
ax.XTickLabel{end-1} = sprintf('\\geq %.1f', edges(end-1));
You can also set the outer edges to -Inf and Inf, as user2305193 pointed out. Since the outer bins are then much wider (because they actually extend to Inf on the x axis), which you can correct by setting the axis xlim. By the default the XTickLabels will display -Inf to -5.0, which I personally don't like, so I set them to lesser (and equal) than and greater than signs.
step = 1;
edges = -5:step:5; % your defined range
edges_inf = [-Inf edges Inf]; % for histogram
edges_ext = [edges(1)-step edges]; % for the xticks
x = 5*randn(1000,1);
% plot the histogram
figure();
ax = axes;
h = histogram(x, 'BinEdges', edges_inf, 'Normalization', 'probability');
labels = [edges_inf(1:end-1); edges_inf(2:end)];
labels = labels(:);
ax.XTick = edges_ext + step/2;
ax.XTickLabel = sprintf('%.1f to %.1f\n', labels);
ax.XTickLabelRotation = 90;
% show all bins with equal width (Inf bins are in fact wider)
xlim([min(edges)-step max(edges)+step])
% set boundary labels
ax.XTickLabel{1} = sprintf('\\leq %.1f', edges(1));
ax.XTickLabel{end-1} = sprintf('\\geq %.1f', edges(end));

Using roof of a graph as x-axis for another

I've plotted a graph using pcolor which gives me the following graph-
My aim is to use the roof of the graph (by roof) I mean the highest axis (in this case, the line which is defined by y=57) as the base for a further graph.
I was able to use hold on to generate the following-
Code for this (removed some parts that defined the axis labels etc for brevity)-
load sparsemap ;
load d ;
residues = 57 ;
z = zeros(residues,residues); % define the matrix
index = find(sparsemap(:,3) ~= 0) ;
values = length(index);
hold on
%Plots the map you see in the first photo-
for k = 1:values
z(sparsemap(index(k),1),sparsemap(index(k),2)) = sparsemap(index(k),3);
z(sparsemap(index(k),2),sparsemap(index(k),1)) = sparsemap(index(k),3);
end
%Plots the line plot at the bottom of the graph.
A = d(:,1);
B = d(:,2) ;
plot(A, B) ;
pcolor(1:residues,1:residues,z);
works = load('colormap_works');
colormap(works);
colorbar;
As you can see, the line plot is using the same x axis as the first graph.
I am trying to get the line plot to come on top of the figure. I imagine a final figure like so-
Any ideas as to how I can use the top part of the first graph?
You can use 2 subplots. Here is an example:
data = randi(50,20,20); % some data for the pcolor
y = mean(data); % some data for the top plot
subplot(5,1,2:5) % create a subplot on the lower 4/5 part for the figure
pcolor(data) % plot the data
colormap hot;
h = colorbar('east'); % place the colorbar on the right
h.Position(1) = 0.94; % 'push' the colorbar a little more to the right
ax = gca;
pax = ax.Position; % get the position for further thightning of the axes
ax.YTick(end) = []; % delete the highest y-axis tick so it won't interfere
% with the first tick of the top plot
subplot(5,1,1) % create a subplot on the upper 1/5 part for the figure
plot(1:20,y) % plot the top data
ylim([0 max(y)]) % compact the y-axis a little
ax = gca;
ax.XAxis.Visible = 'off'; % delete the x-axis from the top plot
ax.Position(2) = pax(2)+pax(4); % remove the space between the subplots
Which creates this:

Plotting a 3D graph of normalized prices in MatLab

I'm doing Gaussian processes and I calculated a regression per year from a given matrix where each row represents a year , so the code is:
M1 = MainMatrix; %This is the given Matrix
ker =#(x,y) exp(-1013*(x-y)'*(x-y));
[ns, ms] = size(M1);
for N = 1:ns
x = M1(N,:);
C = zeros(ms,ms);
for i = 1:ms
for j = 1:ms
C(i,j)= ker(x(i),x(j));
end
end
u = randn(ms,1);
[A,S, B] = svd(C);
z = A*sqrt(S)*u; % z = A S^.5 u
And I wanna plotting each regression in a Graph 3D as the below:
I know that plot is a ribbon, but I have not idea how can I do that
The desired plot can be generated without the use of ribbon. Just use a surf-plot for all the prices and a fill3-plot for the plane at z=0. The boundaries of the plane are calculated from the actual limits of the figure. Therefore we need to set the limits before plotting the plane. Then just some adjustments are needed to generate almost the same appearance.
Here is the code:
% generate some data
days = (1:100)';
price = days*[0.18,-0.08,0.07,-0.10,0.12,-0.08,0.05];
price = price + 0.5*randn(size(price));
years = 2002+(1:size(price,2));
% prepare plot
width = 0.6;
X = ones(size(price,1),1)*0.5;
X = [-X,X]*width;
figure; hold on;
% plot all 'ribbons'
for i = 1:size(price,2)
h = surf([days,days],X+years(i),[price(:,i),price(:,i)]);
set(h,'MeshStyle','column');
end
% set axis limits
set(gca,'ZLim',[-20,20]);
% plot plane at z=0
limx = get(gca,'XLim');
limy = get(gca,'YLim');
fill3(reshape([limx;limx],1,[]),[flip(limy),limy],zeros(1,4),'g','FaceAlpha',0.2)
% set labels
xlabel('Day of trading')
ylabel('Year')
zlabel('Normalized Price')
% tweak appearance
set(gca,'YTick',years);
set(gca,'YDir','reverse');
view([-38,50])
colormap jet;
grid on;
%box on;
This is the result:
That's a ribbon plot with an additional surface at y=0 which can be drawn with fill3

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