I have two vectors(?) of data - one being prices, and the other the dates that those prices occured, and I am trying to plot a scatter plot of the two.
My dates are of the format ddmmyyyy and I have tried using mat2str to convert the vector into strings, and then used
formatin='ddmmyyy';
datenum(MYDATA,formatin)
however it returns an error saying that datenum has failed.
EDIT
This is the example of my code
This is what I am trying to run, where AvivaDate is a vector of 1200x1 double. The problem seems to be that mat2str is not changing the vector into a string of numbers: e.g. I need it in {'12345','12345'} form but mat2str is changing it into a string of '[12345' 12345]', so not a list of separate strings if that makes sense
formatin = 'ddmmyyyy';
DateAviva = mat2str(AvivaDate);
datenum(DateAviva,formatin);
hist(ReturnAviva,datenum(AvivaDate,formatin));
datetick('x','keepticks','keeplimits');
mat2str is not the function you want to convert between numbers and strings. mat2str has a very specific function (you see how it puts the [] around the output?). Use num2str, then convert it into a cell array:
S = num2str(AvivaDate); % should be 1200 x 8 char
C = mat2cell(S,ones(size(S,1),1)); % should be 1200 x 1 cell
dates = datenum(C,'ddmmyyyy'); % should be 1200 x 1 datenums
Although, depending where you're getting the information from in the first place, there may be a better way of reading the dates in from file, so you don't end up with a matrix of numbers where you want dates in the first place.
Related
I am trying to plot a timeseries using a cell array of strings representing an hour of measurements with a sample every 10 seconds. Below is the code I use to plot this data:
Voltages=[230.1,235.1,.......237];
Time={'13:00:10','13:00:20', '13:00:30'........'14:00:00'};
t=timeseries(Voltages, Time); % Using timeseries function in MATLAB
plot(t);
I also add two straight lines showing upper and lower voltage limits, and here is the chart I get:
As you can see in final result an unexpected date is shown on the x-axis ...
I want to do one of the following:
Remove the date altogether from the x-axis.
Using a date string 06.05.2015 I have in a variable, add this date instead of the 1-Jan-2015 unexpected date.
Remove the unexpected date from x-axis and then add the 06.05.2015 in text box.
From the documentation of timeseries class:
ts = timeseries(data,time) creates the time-series object using the specified data and time.
Where time above is a "time vector" as defined further down on the same documentation page:
Time Vector
A time vector of a timeseries object can be either numerical (double) values or valid MATLAB date strings.
When the timeseries TimeInfo.StartDate property is empty, the numerical time values are measured relative to 0 (or another numerical value) in specified units. In this case, the time vector is described as relative (that is, it contains time values that are not associated with a specific start date).
Before plotting the timeseries, try setting the TimeInfo.StartDate to what you need it to be, as shown in the example below:
Time = ['13:00:10';'13:00:20';'13:00:30'];
Data = [1 2.5 3];
start_date = '06.05.2015'; %// What you specified
ts = timeseries(Data,Time);
%// Since a date format separated with dots isn't supported in MATLAB, we replace . => /
ts.TimeInfo.StartDate = strrep(start_date,'.','/');
plot(ts)
Which results in:
This question already has answers here:
What is the Small "e" in Scientific Notation / Double in Matlab
(2 answers)
Closed 7 years ago.
How can I write a number/Integer value to power of 10, e.g. 1000 as 10^3? I am writing code whose output is a string of very large numbers. My output in longEng format is:
4.40710646596169e+018
16.9749211806197e+186
142.220634811050e+078
508.723835280617e+204
1.15401317731033e-177
129.994388899690e+168
14.3008811642810e+153
1.25899227268954e+165
24.1450064703939e+150
627.108997290435e+144
2.03728822649372e+177
339.903986115177e-066
150.360900017430e+183
5.39003779219462e+135
183.893417489826e+198
648.544709490386e+045
19.7574461055182e+198
3.91455750674308e+102
6.41548629454028e-114
70.4943280639616e+096
19.7574461055182e+198
3.11450571506133e-009
249.857950606210e+093
4.64921904682151e+180
750.343029004712e+147
I want these results to be in a format of power of 10, so that I can easily do arithmetic operations for my next function.
you can write format shortE and see you output like this:
4.4071e+18
1.6975e+187
1.4222e+80
5.0872e+206
If you only want to print the data in scientific format, the Matlab itself can do this for you.
If you can to obtain the scientific notation form as
a * 10^b,
i.e., obtain the coefficient a and the exponent b, you can first obtain the b as:
b = floor(log10(abs(x)));
then the a as:
a = x * 10^(-b);
from my understanding you wish to take your number e.g. 4.40710646596169e+018 and split it up into:
4.40710646596169 and 018 once you have them separated you you can perform operations as you wish.
You can even join them back to look like: 4.40710646596169^018 if you so desire (although to look like that they would be strings and therefore mathematical operations on the number would be NAN).
Since e represents to the power 10 and is present in all numbers you listed this is a simple process with many solutions, here is one.
% format long is very important otherwise it will appear to you that you have
%lost precision. MATLAB hides precision from view to save screen space and to
%produce less confusing results to the viewer. (the precision is still there but
%with format long you will be able to see it.
format long
x = 4.40710646596169e+018;
%convert your number into a string, this will allow you to split the number based
%on the always present e+ 'delimiter' (not really a delimiter but looks like one')
s = num2str(x);
%use strsplit to perform the split in the required place. it will output a 1x2
%cell
D = strsplit(s, {'e+'});
%extract each cell to a separate variable. in fact D{1} can be directly used for
%the input of the next function.
D11 = D{1};
D22 = D{2};
%convert the separated strings back into numbers with double precision (keep
%maintin value accuracy)
D1 = str2double(D11)
D2 = str2double(D22)
in order to do this operation on an entire column vector it is simply a matter of using a for loop to iterate through all the numbers you have.
I am trying to build a finantial application that handle economical data using Matlab. The file I want to load is in a csv file and are double numbers in this format '1222.3'. So far, I am just working with one dimension and I am able to load the data into a vector.
The problem is that the data is loaded into the vector in String format. To change all the vector into double format I use str2double(vector), but the numbers into the vector end like this:
1222.3 -> 1.222
153.4 -> 0.1534
I have tried to multiply the vector per 100 (vector.*100), but did not work.
Any idea?
If your vector components are sufficiently large enough, MATLAB will print the numbers in exponential format.
>> a = 1234.56
a =
1.2346e+03
The numbers are also shown in scientific notation in the workspace browser:
You can print the numbers in decimal form using e.g. fprintf:
>> fprintf('%5.3f\n',a)
1234.560
>>
As a side note, 1.222 * 100 ≠ 1222 ...
Matlab automatically pulls some common factor out numerical vectors, which has confused me many times myself. The line that gives the common factor is easy to miss, especially for large vectors, because it is displayed at the top.
If I define a vector with the two number you gave, Matlab displays it to me in the following way:
It pulled out a factor of 1000, as indicated by the line 1.0e+03 *.
I have been searching various forums for hours but it seems impossible to do a thing in Matlab that's automatic in excel...
I used uiimport to import an xls file with into two arrays (? total newbie), one containing dates for my x-axis and the other the values I want to plot.
I have 180 values. The dates are three dates per month, more or less ranging from May 2008 until now, end of March.
Using
plot(mynumbers)
set(gca,'XTickLabel',dates)
only puts dates for May 2008 on my x-axis!
where did all the other dates go?
Instead using
plot(mynumbers)
set(gca,'XTick',mynumbers,'XTickLabel',dates)
gives error message
"??? Error using ==> set
Values must be monotonically increasing."
Please help!
where did all the other dates go?
The answer to your first question is that MATLAB only uses the first N number of strings corresponding to the default N number of tick marks on the x axis.
"??? Error using ==> set Values must be monotonically increasing."
The error is telling you that your date ticks must be evenly spaced. Instead of using dates corresponding to your actual data points, you could grab the x tick values that MATLAB automatically assigned to your graph, translate them to text, and then reassign the dates as x tick labels, like so:
% generate example unevenly spaced date vector
time = [now,now+1,now+25,now+28.5,now+36,now+40,now+51,now+65];
% generate random data points
data = rand(size(time));
% plot time vs data, storing the axes handle in the process
figure;
axH = axes;
plot(axH,time,data)
% get the x-axis tick locations
ticLoc = get(axH,'XTick');
% format tick labels (substitute any date format you wish)
ticLab = cellfun(#(x) datestr(x,'mm/dd'),num2cell(ticLoc),'UniformOutput',false);
% apply tick labels
set(axH,'XTickLabel',ticLab)
MATLAB's built-in function datetick also performs similarly.
However, if you zoom afterwards, you won't have accurate tick labels. So you may want to use datetick2 on the File Exchange.
If you're having trouble converting a cell array of dates from Excel into a numeric array, use:
dateNumeric = cell2mat(cellfun(#datenum,dateStrings,'UniformOutput',false));
try set (gca,'XTickLabel',num2str(dates))
I have a matrix containing the date in a cell structure. I managed to convert the date (2nd column) using datenum(), but I am not sure how to add on the time (3rd column)
The data looks like this:
'IBM' 20090602 0 108.410000000000
'IBM' 20090602 500 108.560000000000
My code:
date = datenum(num2str(IBM(:,2)),'yyyymmdd')
Let's review your mistakes first:
You feed datenum with the string 'IBM(:, 2)' instead of the actual array. Discard the quotes.
datenum accepts strings, not numerical values.
A possible solution is converting the second column of your data into an array of strings, and feeding it into datenum, like so:
d = datenum(num2str(vertcat(IBM{:, 2})), 'yyyymmdd');
Note that this is, of course, possible only if the format of the date string is fixed in each row.
EDIT:
To add the values in the third column to the result of datenum, simply do the following:
d + vertcat(IBM{:, 3})
Where d is a column vector of date values obtained from datenum (I assume that you want to do basic addition, since you haven't specified the actual meaning of the timje values in the third column).
In one line, the complete answer would look like this:
datenum(num2str(vertcat(IBM{:, 2})), 'yyyymmdd') + vertcat(IBM{:, 3})
You can straight-up add the time values in when you're converting to datenum. Just convert from what I assumed were minutes (if they're in seconds, add in another *60 to the divisor) to days, which is what MATLAB uses for its datenum calculations.
timestamps = cellfun(#(x,y) datenum(num2str(x),'yyyymmdd')+y/(24*60),...
IBM(:,2),...
IBM(:,3),...
'UniformOutput',false)