I am trying to plot a graph that has dates (I want years and months as x-ticks). But when I try to plot the graph I either get the correct ticks but no graph showing (this is when I have ax.plot()... at the end) or the graph showing but getting the error (Failed to convert value(s) to axis units: numpy.datetime64('2020')). I don't know how to fix this.
This is my piece of code:
years = mdates.YearLocator()
months = mdates.MonthLocator()
years_fmt = mdates.DateFormatter('%Y')
fig, ax = plt.subplots(1,1, figsize = (10,10))
ax.plot(Date_of_report, Total_reported)
#format ticks
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(years_fmt)
ax.xaxis.set_minor_locator(months)
#round nearest years
datemin = np.datetime64(Date_of_report[0], 'Y')
datemax = np.datetime64(Date_of_report[-1], 'Y') + np.timedelta64(1, 'Y')
ax.set_xlim(datemin, datemax)
ax.format_xdata = mdates.DateFormatter('%Y-%d-%m')
ax.grid(True)
fig.autofmt_xdate()
fig.show()
I've found the solution. When importing the data I imported the dates as string. Instead I imported it as dtype='datetime64[ns]'
np.loadtxt('/content/gdrive/MyDrive/corono/COVID-19_uitgevoerde_testen.csv',\
delimiter =';',skiprows=1, usecols=2, dtype='datetime64[ns]')
Related
I want to know the number of days of each month from 1982-01-01 to 2015-12-31.
I tried some codes from Matlab Help. till now I wrote this code:
t1 = datetime(1982,01,01); %start date
t2 = datetime(2015,12,31); %end date
T = t1:t2; %creating a range
no idea how to do it. in the end, I want to have one array (1*408)
thank you all
Here's one approach. See ndgrid and datenum.
years = 1982:2015; % desired range of years
[mm, yy] = ndgrid(1:12, years); % all pairs of month, year
result = datenum(yy(:), mm(:)+1, 1) - datenum(yy(:), mm(:), 1); % adding 1 to the month
% works even for December. 'datenum' gives a result where each unit is one day
First of all, I think the answers I've found are outdated:
Excluding weekend gaps from financial timeseries plots
Exclude Date Gaps in Time Series Plot in Matlab
Datetick take into account NaN in plot
My problem:
I've created a candlestick graph based on a Timetable table with these dates (the format is dd/mm/yyyy):
'25/01/2019'
'24/01/2019'
'23/01/2019'
'22/01/2019'
'21/01/2019'
'18/01/2019'
'17/01/2019'
'16/01/2019'
'15/01/2019'
'14/01/2019'
'11/01/2019'
'10/01/2019'
'09/01/2019'
'08/01/2019'
'07/01/2019'
'04/01/2019'
'03/01/2019'
'02/01/2019'
'28/12/2018'
'27/12/2018'
'26/12/2018'
'21/12/2018'
'20/12/2018'
'19/12/2018'
'18/12/2018'
And this code:
candle(this.values);
This gives me this plot:
As you can see, there are gaps corresponding to the non-business days.
Given the answers that I've found to the same problem what I did was:
Created two arrays one with the dates and the other with dates strings:
this.dates = table2timetable(ticker(1:5:25,:));
%sort them out because were generated in reverse order
this.dates = timetable2table(sortrows(this.dates(:,1)));
this.dates = this.aux(:,1);
this.lbl = datestr(this.aux{:,1},'dd/mm/yyyy');
Obtain the gca object to set the X-axis properties:
this.ax = gca;
this.ax.XTick = this.dates{:,1};
this.ax.XTickMode = 'manual';
this.ax.XTickLabel = this.lbl;
And the result is this:
So the properties are being set correctly but the gaps remain.
Finally I've tried to set the Timetable property VariableContinuity and called the retime function to generate the missing dates entries with NaN data to see if that helped but with the same results:
this.values.Properties.VariableContinuity = {'event','event','event','event','event','event','event','event'};
this.values = retime(this.values,'daily');
What else could I do to hide the gaps?
I believe that once plotted, you cannot remove the gaps. You have to remove the gaps before plotting. In your timetable, create a linear date array (no gaps) and use this for the timetable, then plot. Then, the gaps will not be there but the dates will be wrong. To put the right date, use the following code (similar to your code).
this.ax.XTickMode = 'manual';
this.ax.XTickLabel = YOUR_CORRECT_DATE_CELL_ARRAY
I'm trying to plot 63 years of monthly data and some labels are repeating (indicated by arrows), illustrated by the following figure:
In order to handle x-labels, I used the following code:
xdate = datenum (datestring2, 'yyyy/mm');
plot (xdate,data1.data(:,4), 'b', xdate,data1.data(:,6),'r', ...
xdate,data1.data(:,8),'k', xdate,data1.data(:,10),'g');
xtic=xdate(1):12:xdate(end);
set(gca,'XTick',xtic);
datetick('x', 'mm/yyyy', 'keepticks');
How can I solve that issue?
You can exploit the carryover feature of datenum():
out = datenum(2000,1:14,1);
Let's verify:
datestr(out)
ans =
01-Jan-2000
01-Feb-2000
01-Mar-2000
01-Apr-2000
01-May-2000
01-Jun-2000
01-Jul-2000
01-Aug-2000
01-Sep-2000
01-Oct-2000
01-Nov-2000
01-Dec-2000
01-Jan-2001
01-Feb-2001
Now set them as Xtick:
set(gca,'Xtick',out)
EDIT: use start end dates
% Provide example initial and final date
in = '20100324';
fi = '20130215';
% Decompose with datevec, count number of months, and skip one month if day > 1
infi = datevec({in,fi},'yyyymmdd');
nmonths = diff(infi(:,1:2))*[12 1]' + infi(1,2);
skipone = infi(1,3) ~= 1;
% Calculate dates
out = datenum(infi(1), (infi(1,2) + skipone):nmonths, 1);
Your expression xtic=xdata(1):12:xdate(end) says that you want a tick every 12 days; often that means you will get two (or even three) repeated months. A quick and dirty solution is
xtic = xdata(1):30:xdate(end);
But that may in some situations skip February, and will be wrong when you run for a large number of months.
To get around this properly, you need to place ticks at the first of every month. A possible way to do that is this:
xdate = datenum(datestring2, 'yyyy/mm');
d1 = datevec(xdate(1)); % [year, month, date, hour, min, sec]
d2 = datevec(xdate(end)+30); % one month past the last data point
nm = ceil((xdate(end) - xdate(1))*12/365); % whole number of months
mv = mod((1:nm) + d1(2) - 2, 12) + 1; % months
yv = d1(1) + floor(((1:nm) + d1(2) - 1)/12); % years
ymdv = [yv' mv' ones(nm,1)]; % year, month, day for each tic
xtic = datenum(ymdv); % will turn this into "the first of every month"
EDIT Oleg Komarov's answer points to a much cleaner way to generate tics at every first of the month - this is using the fact that datenum can cope with months greater than 12. You could probably make the above code a little more compact and cleaner by using that approach (for example, you could leave out the mod operation for mv, and just use d1(1) for the year). But sometimes being explicit about what you are doing isn't a bad thing.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calculations of files
Day price1 price2
2/2/2000 10 15
3/2/2000 12 18
4/2/2000 14 19
How could I plot x=day and y=price1?
file = xlsread('example.xls');
x = file(:,1);
y = file(:,2);
plot(x,y);
It doesn't give the days in x line it gives numbers 0, 1, 2 insted of 2/2/2000
The neatest method for getting the x-axis to display dates is via the datetick function. I used to do it manually, as the other answers to this question suggest doing, until I discovered this wonderful function.
Cut and paste the following example into a Matlab script and run it line-by-line:
y = randn(4, 1); %# Simulate random observations
Dates = {'1/1/2000', '2/1/2000', '3/1/2000', '4/1/2000'}; %# Build a vector of date strings
DatesNum = datenum(Dates, 'dd/mm/yyyy'); %# Convert date strings to date numbers
plot(DatesNum, y); %# Plot the data
datetick('x', 'dd/mm/yyyy'); %# Convert date numbers on plot to string format
The last line essentially says "on the x axis of the current plot, display the numbers in date-time format, using the format string dd/mm/yyyy".
Once you are familiar with how this example works, you should be able to adapt this example to your code.
You can use date strings to label your xtick marks in the plot. First we need to convert the date number to a date sting, using datestr.
[file, text] = xlsread('example.xls');
x = file(:, 1);
y = file(:, 2);
x0 = datenum(2000, 2, 2);
cal = cellstr(datestr(x + x0));
Then we can plot and label the tickmarks.
plot(x, y);
set(gca(), 'xtick', 1 : length(y), 'xticklabel', cal);;
If you do not have an Excel COM server available (likely the case if you are running on unix/linux), the dates will appear as Excel serial date numbers (an integer). These are different from MATLAB date serial numbers. They can be converted using x2mdate():
file = xlsread('example.xls')
file(:,1) = x2mdate(file(:,1))
set(gca,'Xtick',file(:,1),'XTickLabel',datestr(file(:,1)))
Here I am assuming that the dates in your date column are formatted as dates by Excel/LibreOffice and not as strings.
In Matlab, I have several txt files that I have loaded and converted to matrices. The matrices represent temperature data at different cities around the world. The first column in each matrix is a year. Each file spans a different range of years but they all overlap for a few of those years. I would like to find where the overlap, and either extract out (or delete non-overlapping years) so that when I plot the data, each data set is using the same span of years. The code should be able to ingest an unknown number of these txt files. I have tried to use the "intersect" function but that will work on an element-by-element basis. I want all data for overlapping years, so the elements (except for the header) will be different.
An example of current code:
clear all
files = dir('.txt');
num_files = length(files);
mintersect(files);
for i=1:num_files
eval(['load ' files(i).name ' -ascii']);
vals{i} = load(files(i).name);
matrix = vals{i};
station = (files(i).name(1:end-4));
matrix(matrix == 999.9) = NaN;
matrix(matrix == -99.0) = NaN;
years = matrix(:,1);
months = matrix(:,2:13)';
figure, hold on
plot(years, months,'');
ylabel('Temp.');
xlabel('Years');
grid on;
title(sprintf('Mean Monthly Temperature for %s Station',station));
end