How can I represent the vectors below as box plot? - matlab

I have below these three vectors:
CoverageArea_mean = [84.4735,0,21.1779,4.5211,6.4247,2.3795,2.1416,0]; %FEC = 3.8x10^-3
CoverageArea_min = [98.5128,92.5640,21.1779,21.1779,6.9007,6.9007,2.1416,2.1416]; %FEC = 3.8x10^-3
CoverageArea_max = [70.1963,0,19.0363,0.4759,5.9488,0.2380,2.1416,0]; %FEC = 3.8x10^-3
I would like to draw them as in the figure below:
x = [15 15 30 30 45 45 60 60];
I am not sure If they will be fit for the box plot or not. I want to take a value from the three vectors every time and represent them as a above.
Any idea or assistance, please?

1.- I call marker (as in oscilloscopes) what in MATLAB is called pointer.
2.- I have modified Davidson's function plot_candlesticks available here
https://uk.mathworks.com/matlabcentral/fileexchange/9893-candlesticks?s_tid=srchtitle_financial%20charts_23
Mathworks File exchange name: candlesticks version 1.0.0.0 (1.44 KB) by Bill Davidson
Bill grants permission for modifications.
3.- With the following functions and test script you can generate graphs like this
The addition of text labels is a really easy task that I have started, as you can see in the test script, but ran out of time for this question so I let you finish it off, let me know if you encounter any problem.
I recommend you use command text outside the supplied functions, after plotting the graph
4.- I give you 2 functions: plot_tees and plot_bars . The function you asked for is plot_tees
function [hpt]=plot_tees(ax1,x,highs,lows,opens,closes,sh,col_stick)
% plot_tees plots T and inverted T on supplied data points
% input checks: PENDING
% make sure x has no gaps and same interval
% make sure all input lengths are the same : x highs lows opens closes
% check amount inputs and expected formats ok
middle=sh.middle
hwbody=sh.hwbody
hwshad=sh.hwshad
xbody=sh.xbody
xshad=sh.xshad
npoints=length(highs);
hpt=[0 0 0];
for k1=1:npoints
hp1(k1,1)=plot(ax1,[.5+x(k1)-.2 .5+x(k1)+.2],[highs(k1) highs(k1)],'Color',col_stick,'LineWidth',1.1); % top --
hp1(k1,2)=plot(ax1,[.5+x(k1)-.2 .5+x(k1)+.2],[lows(k1) lows(k1)],'Color',col_stick,'LineWidth',1.1); % low --
hp1(k1,3)=plot(ax1,[.5+x(k1) .5+x(k1)],[lows(k1) highs(k1)],'Color',col_stick,'LineWidth',1.1); % the actual stick
hpt=[hpt; hp1];
end
hpt(1,:)=[];
end
and plot_bars
function [hpt]=plot_bars(ax1,x,highs,lows,opens,closes,col_down,sh,col_up)
% plot_bar plots high-low bars on supplied data
% input checks
% make sure x has no gaps and same interval
% make sure all lengths are the same :x highs lows opens closes
middle=sh.middle
hwbody=sh.hwbody
hwshad=sh.hwshad
xbody=sh.xbody
xshad=sh.xshad
npoints=length(x);
colors=closes<opens;
colors=char(colors*col_down+(1-colors)*col_up); % 'k' black 'w' white 'r' red 'b' blue or custom RGB [r g b] range [0 1]
% h1=figure(1)
hpt=[];
for k1=1:npoints
hp1=patch(ax1,x(k1)+xbody,[opens(k1),opens(k1),closes(k1),closes(k1),opens(k1)],colors(k1));
hpt=[hpt hp1];
end
end
This is the TEST SCRIPT HERE :
close all;clear all;clc
% opns : opens clos : closes , avoiding var names too close to reserved names
col_down='r'
col_up='r'
col_stick='k'
% this is to avoid having to make changes inside each function
sh.middle=0.5;
sh.hwbody=sh.middle/2;
sh.hwshad=sh.hwbody/10;
sh.xbody=sh.middle+[-sh.hwbody sh.hwbody sh.hwbody -sh.hwbody -sh.hwbody];
sh.xshad=sh.middle+[-sh.hwshad sh.hwshad sh.hwshad -sh.hwshad -sh.hwshad];
% time reference
npoints=15 % amount CONSECUTIVE days
x=[1:npoints] % day points
% data
y_mean0=50 % DC to avoid graph 002
y=rand(npoints,1)-0.5
opns=y_mean0+cumsum(y)
highs=opns+rand(npoints,1)
lows=opns-rand(npoints,1)
clos=opns+(highs-lows).*(rand(npoints,1)-0.5)
% plot frame
h1=figure(1)
ax1=gca
plot(ax1,[x(1)-1 x(end)+1],[y_mean0 y_mean0])
hold(ax1,'on')
plot(ax1,x,zeros(1,numel(x))+y_mean0,'|','Color',[.7 .7 .7]) % days reference
% plot data spans
hp1=plot_tees(ax1,x,highs,lows,opns,clos,sh,col_stick);
hold on
grid on; % off | minor
hp2=plot_bars(ax1,x,highs,lows,opns,clos,col_down,sh,col_up);
% include text tags
prec=7 % precision : amount total digits into string '.' not a digit
str_highs=num2str(highs,prec);
str_lows=num2str(lows,prec);
tr1=2 % trim, in case needed : how many decimal digits to drop from right hand side
str_highs(:,[end-tr1+1:end])=[];
str_lows(:,[end-tr1+1:end])=[];
% PENDING
% figure properties
h1.Name='graph 01';
h1.NumberTitle='off';
h1.ToolBar='auto'; % none | figure
h1.MenuBar='figure'; % | figure
h1.Color=[.7 .7 .7]; % figure background colour
ax1.Color=[.9 .9 .9]
% T-marker properties : modify T-marker properties here
for k1=1:1:size(hp1,1)
for k2=1:1:size(hp1,2)
hp1(k1,k2).LineWidth=1.1;
hp1(k1,k2).Color=[.9 .5 .3];
end
end
% bars properties : modify bar properties here
for k1=1:1:size(hp2,2)
hp2(k1).EdgeColor='none';
end
% plot aditional graphs
plot(ax1,x+.5,opns,'c','LineWidth',1.5)
5.- I am not using the data you supplied in the question. Instead I use randomly generated points.
You should have no trouble in replacing the random data with your data.
Let me know if any handicap.
5.1.- The time reference you supplied doesn't seem to match the supplied values; x has doubled values and there are more values than days
5.2.- The mean value hardly ever is exactly the average between each high and each low
5.3.- Using the data I know I could show how to do things like changing properties and including additional graphs, because with a clear time reference is available.
6.- Because you may need to change colours, bars opacity, bars edge, bars presence, and thickness of any, as well as there may be need to turn on/off each text field on graph (of each point and of all points) all handles to properties are now available.
Additional Comments :
7.- MATLAB built-in colours handy here
And some other commonly used custom colours
Any colour is available, just specify the RGB as vector [1 1 1] range of each element [0 1] 0: black, 1: white.
8.- MATLAB built-in markers are : arrow (default) ibeam crosshair watch topl botr circle cross fleur left right top bottom and hand.
One can also create custom pointers setting up figure property PointerShapeCData.
But none of these pointers are useful here because they are all 16x16 only, size matters.
This is why I asked in first place if the Ts had to be same size, or more reasonably, like in financial/investment/banking graphs you asked for T-markers proportional to the specified span, for each point.
9.- This question-answer has nothing to do with what is commonly known as T-graphs : 2 lists side by side to compare features.
10.- use uifigure instead of figure if you are building your app with App Builder.

Related

comparing generated data to measured data

we have measured data that we managed to determine the distribution type that it follows (Gamma) and its parameters (A,B)
And we generated n samples (10000) from the same distribution with the same parameters and in the same range (between 18.5 and 59) using for loop
for i=1:1:10000
tot=makedist('Gamma','A',11.8919,'B',2.9927);
tot= truncate(tot,18.5,59);
W(i,:) =random(tot,1,1);
end
Then we tried to fit the generated data using:
h1=histfit(W);
After this we tried to plot the Gamma curve to compare the two curves on the same figure uing:
hold on
h2=histfit(W,[],'Gamma');
h2(1).Visible='off';
The problem s the two curves are shifted as in the following figure "Figure 1 is the generated data from the previous code and Figure 2 is without truncating the generated data"
enter image description here
Any one knows why??
Thanks in advance
By default histfit fits a normal probability density function (PDF) on the histogram. I'm not sure what you were actually trying to do, but what you did is:
% fit a normal PDF
h1=histfit(W); % this is equal to h1 = histfit(W,[],'normal');
% fit a gamma PDF
h2=histfit(W,[],'Gamma');
Obviously that will result in different fits because a normal PDF != a gamma PDF. The only thing you see is that for the gamma PDF fits the curve better because you sampled the data from that distribution.
If you want to check whether the data follows a certain distribution you can also use a KS-test. In your case
% check if the data follows the distribution speccified in tot
[h p] = kstest(W,'CDF',tot)
If the data follows a gamma dist. then h = 0 and p > 0.05, else h = 1 and p < 0.05.
Now some general comments on your code:
Please look up preallocation of memory, it will speed up loops greatly. E.g.
W = zeros(10000,1);
for i=1:1:10000
tot=makedist('Gamma','A',11.8919,'B',2.9927);
tot= truncate(tot,18.5,59);
W(i,:) =random(tot,1,1);
end
Also,
tot=makedist('Gamma','A',11.8919,'B',2.9927);
tot= truncate(tot,18.5,59);
is not depending in the loop index and can therefore be moved in front of the loop to speed things up further. It is also good practice to avoid using i as loop variable.
But you can actually skip the whole loop because random() allows to return multiple samples at once:
tot=makedist('Gamma','A',11.8919,'B',2.9927);
tot= truncate(tot,18.5,59);
W =random(tot,10000,1);

Matlab: Intraday Time Series Plotting Issue

Can you help me with the following issue?
I have a large dataset of intraday financial data. More specifically, closing stock prices of each 15 minutes for multiple days. I face a problem in plotting the timeseries of the data.
Here is an example of my series:
'29-Dec-2016 15:00:00' 62.8400000000000
'29-Dec-2016 15:15:00' 62.8300000000000
'29-Dec-2016 15:30:00' 62.8900000000000
'29-Dec-2016 15:45:00' 62.8550000000000
'29-Dec-2016 16:00:00' 62.8900000000000 (Closing of the market)
'30-Dec-2016 09:45:00' 62.7300000000000 (Opening of the market)
'30-Dec-2016 10:00:00' 62.2900000000000
'30-Dec-2016 10:15:00' 62.2400000000000
'30-Dec-2016 10:30:00' 62.0900000000000
'30-Dec-2016 10:45:00' 62.1100000000000
'30-Dec-2016 11:00:00' 62.3000000000000
'30-Dec-2016 11:15:00' 62.2300000000000
If I plot the above subsample the matlab plot will have a form like the following picture:
As you can see the Matlab plotting fills in the horizontal axis with the time between the closing of the market and the opening of the market which makes the price to look "stretched".
Contrary if i use an increasing observation number (e.g. 1 to 100...) the problem is removed like in the following picture:
Is there a way to avoid the "stretch" of the price and still have time on my horizontal axis?
Thanks in advance.
You can do this way:
First plot only price data
plot(price)
Then set the XTickLabel:
set(gca,'XTickLabel',datevector)
This will set the X axes with your data
You can put this inside a function
function plotprices(data)
datevector = data(:,1); %store dates in first column
price = num2cell(data(:,2)); %store prices in second column
plot(price)
set(gca,'XTickLabel',datevector)
You can read the positions of the x-ticks on the plot and replace their labels with your own strings. So, assuming:
a) y has the stock prices, and
b) Date has the date strings,
you could add the following code at the end of the second plot to get something close to what you want:
% limit the x-axis such that all ticks are within the data range
xlim([1, length(y)]);
% read the marks of the x-ticks
xt=get(gca, 'XTick');
% this would place the x tick marks at the same locations
% that Matlab chose by default. If you want to place them
% at some other points, just assign those points to xt, e.g.
% xt = (1:10:length(y))
% replace the labels of the marks
set(gca, 'XTick', xt); % rewrite this in case you modify xt
set(gca,'XTickLabel',Date(xt))
BTW, a potentially simpler alternative is to use your first plot but instead of solid line, use markers only. For example, plot(Date, y, '.');

How tick labels on one of the plot's axis can be multiplied in MATLAB?

I am currently trying to make 'nice looking' axis on my plot in Matlab. The values are samples where each is taken every 20ms. So on X axis I'd like to have time in ms. My general code for plotting data is very simple:
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
So far I've been able to correctly display sample numbers on this axis:
Code:
set(gca,'XTick',(1:size(data.matrix,1))*20);
Result (a):
In the given example the number of samples equals 184, that makes:
time = 184 * 20ms = 3680ms
Because changing the XTick value didn't do much of a change, I've tested XTickLabel property:
Code:
set(gca,'XTickLabel',ceil(linspace(0,size(data.matrix,1)*20,10)));
Result (b):
Code:
set(gca,'XTickLabel',0:ceil((size(data.matrix,1)*20)/10):size(data.matrix,1)*20);
Result (c):
As you may see, the results aren't the worst one. But this is not what I am trying to achieve. My goal is to have values like this:
So it simply first plot's (result a) X axis multiplied by 20.
Can someone please tell me how to achieve this?
when you use :
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
The first parameter 1:size( data.matrix,1) create a vector of consecutive integers representing the indices of your data points. Two things are wrong with that:
1) You do not need to specify it. Matlab plot function called with only the Y data will create this vector automatically and use it to plot the data.
2) These indices represent the position of your data in an array, they have no physical meaning (like "time" for your case).
The solution is to create a proper 'time' vector and send it as the first parameter to the plot function. This way Matlab will take care of the tick management and you don't have to temper with the manual xtick settings.
Look at the two ways of doing it in the example below and everything will be clear:
%// build a simple index "X" vector (as you were doing)
x_index = 1:size(data.matrix,1) ;
%// build a properly scaled time vector
timeInterval = 20 ; % in milliseconds
x_time = ( 0:size(data.matrix,1)-1 ) * timeInterval ;
plot( x_index , data.matrix(:,1) ) %// this will do like in your example
plot( x_time , data.matrix(:,1) ) %// this will do what you want
Can you not just do?
set(gca,'XTickLabel',(1:size(data.matrix,1))*20*20);

Matlab Plot Smoothing having no effect

I'm currently having some trouble with the 'smooth' command, namely that it seems to have no effect on the generated plot. I have already used the following script to generate a plot
for h=1:4
linespec = {'rx', 'gx', 'bx', 'yx'};
hold on
for b=1:365
y=mean(mean(A(b,6*(h-1)+1:6*h)));
p(h)=plot(b,y,linespec{h});
end
hold off
end
Going row by row in data set A and taking the average of the values in the first six columns, then column 7 through 12, 13 through 18 and 19 through 14; generating four plots in total.
The next step was to smooth the resultant plot by averaging the values over a span of 9. So, I tweaked the script to the following;
for h=1:4
linespec = {'rx', 'gx', 'bx', 'yx'};
hold on
for b=1:365
y=mean(mean(A(b,6*(h-1)+1:6*h)));
w = smooth(y,9,'moving');
p(h)=plot(b,w,linespec{h});
end
hold off
end
Essentially just adding the w variable and replacing y with w in the plot command. Yet this has no effect whatsoever on my plot. Matlab doesn't throw up any errors either, so there doesn't seem to be a problem with the input size. Does anyone have an idea as to what the issue might be?
In either version of the loop, you appear to be plotting individual values of y against individual values of b. I presume, then, that y is a single value. You can't smooth a point, so the smooth operation is having no effect.
From the start, you don't need to make a loop to calculate the various means; mean can take a 2D matrix and return a vector. Calculate y in one go, then smooth that vector (should have length 365, I presume - depends on the size of input A). e.g.:
b = 1:365;
y=mean(A(:,6*(h-1)+1:6*h),2);
w = smooth(y,9,'moving');
plot(b,y,'rx');
hold on
plot(b,w,'gx');

Plotting multiple figures in Matlab

I am working with some matlab code that processes data (in a Kalman Filter) and creates a series of contour plots. It has been running on a RHEL 4 server in matlab 2006a for a few years, but my boss recently requested that all servers be updated to RHEL 6...and at least matlab 2007a. I have worked out all the depreciations between these versions, but I am still having one major problem.
The code that creates and prints different contour plots is working for whichever of the three plots is created first. It looks like this:
Unfortunately the next two plots look like this:
The three figures are plotted independently in separate functions and I use clf("reset"); before and after creating each figure. Each function works in and of itself, but when all three are plotted the second and third figures are all messed up. Has anyone else had this problem? Here is the code that creates one of the figures.
function Crd = TEC_plot(ITEC,RT,Param,Input,t,OutPath,RxExtAll,Time)
% Generate TEC plot
Function_for_Spline_Smoothing = [.05 .1 .05; .1 .4 .1; .05 .1 .05];
ITEC = conv2(ITEC,Function_for_Spline_Smoothing,'same'); % add more of these lines to make contours smoother
ITEC = conv2(ITEC,Function_for_Spline_Smoothing,'same'); % add more of these lines to make contours smoother
% ITEC = conv2(ITEC,Function_for_Spline_Smoothing,'same'); % add more of these lines to make contours smoother
% ITEC = conv2(ITEC,Function_for_Spline_Smoothing,'same'); % add more of these lines to make contours smoother
earth('CAMERA',RT.Camera,'FIG',1);
figure;
warning off; hold on;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Changed 13 February 2007 to make plots prettier
thinning_scale=2; % (1 to 10) increase this value to thin the density of the contour number labels
[cscale,hgt]=m_contour(Param.Grid.LonAxis,Param.Grid.LatAxis,ITEC, ...
round(RT.Levels(1:thinning_scale:end)/5)*5);
hold on
m_contourf(Param.Grid.LonAxis,Param.Grid.LatAxis,ITEC,RT.Levels);
shading flat
m_coast('line','color','y','LineWidth',1);
clabel(cscale,hgt,'labelspacing',72,'rotation',0,'fontsize',10 ...
,'FontAngle','italic','color','w');
axis([-.65 .6 .25 1.32]) % hardwiring axis length since the coastline runs off of the plot
% Changed 13 February 2007
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %-------------------- to include different station markers for different sources -------------------
if ~isempty(Input.Data) % Plot receivers used in this inversion
Crd=uniquerows(double(cat(1,RxExtAll)));
RxType=round(Crd(:,4));
Crd=cartsph(Crd)*180/pi;
i1 = find( (Crd(:,3) > RT.Camera(3)).*(Crd(:,3) < RT.Camera(4)).*...
(Crd(:,2) > RT.Camera(1)).*(Crd(:,2) < RT.Camera(2)).*...
(RxType==1) );
i2 = find( (Crd(:,3) > RT.Camera(3)).*(Crd(:,3) < RT.Camera(4)).*...
(Crd(:,2) > RT.Camera(1)).*(Crd(:,2) < RT.Camera(2)).*...
(RxType==2) );
i3 = find( (Crd(:,3) > RT.Camera(3)).*(Crd(:,3) < RT.Camera(4)).*...
(Crd(:,2) > RT.Camera(1)).*(Crd(:,2) < RT.Camera(2)).*...
(RxType==3) );
m_plot(Crd(i1,3),Crd(i1,2),'ro','markersize',5,'LineWidth',2);
% m_plot(Crd(i1,3),Crd(i1,2),'r.','markersize',6,'LineWidth',2);
m_plot(Crd(i2,3),Crd(i2,2),'r^','markersize',5,'LineWidth',2);
% m_plot(Crd(i2,3),Crd(i2,2),'r.','markersize',6,'LineWidth',2);
m_plot(Crd(i3,3),Crd(i3,2),'rp','markersize',5,'LineWidth',2);
plot(-.6,.45,'ro','markersize',5,'LineWidth',2);text(-.55,.45,'CORS','Color','k')
plot(-.6,.39,'r^','markersize',5,'LineWidth',2);text(-.55,.39,'GPS/Met','Color','k')
plot(-.6,.33,'rp','markersize',5,'LineWidth',2);text(-.55,.33,'RTIGS','Color','k')
end
% % -------------------------------------------------------------------------------
hold off; warning on;axis off;
% caxis([RT.Levels(1),(RT.Levels(length(RT.Levels)))/2]); colorbar('vert'); %Color bar from 0 to 50 --- for Low Solar Activity
caxis([RT.Levels(1),(RT.Levels(length(RT.Levels)))]); colorbar('vert'); %Color bar from 0 to 100 --- for High Solar Activity
title(sprintf('Total Electron Content Units x 10^1^6 m^-^2'),'Fontsize',11)
if size(Crd,1)==0,
title(sprintf('Total Electron Content Units x 10^1^6 m^-^2 Caution: No Data Available, IRI95 Only'),'Fontsize',10)
end
whitebg('w')
text(-0.6,0.22,sprintf('%s from %s to %s UT NOAA/SWPC Boulder, CO USA (op.ver. 1.0)',datestr(Time(t)+1E-8,1),datestr(Time(t)+1E-8,15),datestr(Time(t)+1E-7+15/1440,15)),'Fontsize',11)
whitebg('w')
% This option print to a file
% set(gcf, 'Position', [0,0,1950,1467]);
% print('-f1','-dpng','-painters',filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC'],Time(t)));
% system(['convert ', filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC.png'],Time(t)),' -scale 650x489 ',' -colors 256 ', filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC.png'],Time(t))]);
% Printing a postscript file because requirements for the automatic reboot
print('-f1','-dpsc','-r1000','-painters', filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC'],Time(t)));
% Convert the postscript file to jpg using ghostscripts
system(['gs -q -dBATCH -dNOPAUSE -r300 -sDEVICE=jpeg -sOutputFile=',filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC.jpg'],Time(t)),' ', filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC.ps'],Time(t))]);
% Converting from jpg to png and reducing the size of the figure.
system(['convert ',filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC.jpg'],Time(t)),' -crop 2050x1675+325+775 ',' -scale 650x489 ',' -colors 256 ', filename([OutPath,'{YYYY}{MM}{DD}{HRMN}_TEC.png'],Time(t))]);
% Removing the jpg and ps files (ask Cliff how can we put both files in just one command)
%system(['rm ',filename([OutPath,'*.jpg'],Time(t))]);
%system(['rm ',filename([OutPath,'*.ps'],Time(t))]);
end
Try to not use clf which will clear your whole figure but use the figure in between to open three independant figures. See it it'll work :)
Edit: That's just guessing without actually seeing your code
One guess might be with the code that generates your final PNG file. Your second figure appears to be incorrectly cropped when converting from JPG to PNG.
First the print command is fixed to use whatever is in figure 1. So, to ensure that you are plotting using figure 1 use the command figure(1) to specify this. Alternatively, change the print command to to read print(gcf ... to print the current figure.
Also, note you could generate the PNG file directly with print as in
print(gcf,'-dpng','-r1000',filename(...))
and skip the conversion from PS to JPG to PNG step.
The hard-coding the figure window in the print might explain why things work independently but not together if the you have multiple figure windows available. Just a guess.