How can I give my x-axis predetermined values (a year)
6 views (last 30 days)
Show older comments
Jan-Willem van de Scheur
on 16 Jan 2018
Commented: John BG
on 17 Jan 2018
I want to give my x-axis certain values, in my case years. So I want let the graph go from 2001 until 2014. In my case the code looks like this:
plot(nu2)
This is a time-serie of 3521 points, which has a range of 14 years.
0 Comments
Accepted Answer
John BG
on 17 Jan 2018
Hi Jan van den Scheur
The problem with Star Strider's suggestion is that the class timeseries as defined, does not include years as units, let me explain:
The fastest way for this particular requirement is to extract the data of the timeseries, if you are using timeseries at all, and plot as follows
1. Extract data and change displayed time reference, not the time reference vector
close all;clear all;clc
n_samples=3521
nu=randi([1 10],1,n_samples);
tnu=[1:1:numel(nu)];
n_years=14;
y01=2000;
str1=num2str([y01:1:y01+n_years]');
n1=table2cell(table(str1))
h1=plot(tnu,nu);ax=gca;grid on
xticks([1:floor(n_samples/n_years):n_samples])
ax.XTickLabel= n1'
.
3521 samples have been generated, and all of them accurately show up on the graph yet the time reference only shows chosen years, for instance 2001 to 2014.
Now let's see what happens when attempting to use timeseries as input to plot such high volume of data but only attempting to show a few time stamps
2. We cannot define timeseries without equal amount samples and time stamps
timeseries variables by definition require 1 and only 1 time stamp for each sample of data.
Obviously one can call a time series to anything else that for instance may have 2 samples per time stamp, but it's not going to be as requested to be a MATLAB class timeseries.
The samples can be complex numbers, or anything else of choice, but the mapping has to be strict: 1 timestamp for each data sample.
Actually the function timeseries returns error when attempting to define a timeseries with mismatched amounts of data and time stamps.
ts1 = timeseries(nu2,tnu);
ts1.Time=[y01:1:y01+n_years]'
plot(ts1)
% error
% Error using timeseries.utreshape (line 846)
% Data and time dimensions are incompatible.
% Error in timeseries/init (line 280)
% [data,quality] = timeseries.utreshape(lenTime,data,quality);
% Error in timeseries (line 324)
% this = init(this,varargin{:});
.
3. trying to redefine the time vector of the time series reducing the amount of time stamps is not going to work either
nt=[1:floor(n_samples/n_years):n_samples]
ts1 = timeseries(nu,nt);
ts1.Time=[y01:1:y01+n_years]'
plot(ts1)
% returns same mismatch error
.
4. undersampling data at the definition point is not an option
% Why then would we have taken such samples anyway?
nt=[1:floor(n_samples/n_years):n_samples]
nu2=nu(nt);
ts1 = timeseries(nu2,nt);
ts1.Time=[y01:1:y01+n_years]'
plot(ts1,'o')
.
.
where has the data gone? we don't want to go down that road, do we?
.
5. time series as defined do not come with years included in the units
The only words allowed in timeseries field Units are the following ones:
Units — Time units having any of following values: 'weeks', 'days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds', or 'nanoseconds'
Attempting to set the units to years doesn't work either, the resulting timeseries is actually damaged when casting a word other than any of those above listed.
ts1.TimeInfo.Units = 'years';
when attempting to use such timeseries
ts1
timeseries
Common Properties:
Name: 'Yearly Count'
Time: [15x1 double]
Error using datenum (line 181)
DATENUM failed.
Error in tsdata.timemetadata/display (line 57)
startstr =
datestr(datenum(this.Startdate)+tsunitconv('days',this.Units)*this.Start,'dd-mmm-yyyy
HH:MM:SS');
Error in timeseries/display (line 50)
locGetHyperLinkDispString(evalc('ts.TimeInfo')), ...
Caused by:
Error using datevec (line 276)
Cannot parse date 2001.
.
5. resampling with command resample also implies losing data:
.
ts0 = timeseries([1.1; 2.9; 3.7; 4.0; 3.0],1:5,'Name','speed');
res_ts0=resample(ts1,[1 3 5]);
figure(1);plot(ts0);figure(2);plot(res_ts0)
.
it's immediately appreciated that removing time samples with command resample in an attempt to just show for instance 'years' on the time reference of a plot causes again loss of data.
So, Jan, with so many points in between plot year samples, neither the linear (default) nor the zoh interpolations are recommended, because again the data will surely be deformed, that if acceptable, then again, why taking so many samples in first place?
So to accurately display data contained in a timeseries, but only show years on the time axis of a plot perhaps you would like to consider the very 1st option suggested in this answer:
If using timeseries, extract data and plot against chosen years overlapping the x axis ticking with such years.
If not using timeseries because of the possible delay that may imply writing specific code meeting timeseries requirements, then the 1st option is also recommended.
.
Jan
if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance for time and attention
John BG
0 Comments
More Answers (1)
Star Strider
on 16 Jan 2018
Setting:
nu2.TimeInfo.Format = 'yyyy';
may do what you want.
2 Comments
Jan
on 17 Jan 2018
Then years can appear multiple times in the ticks. But you can set the ticks explicitly also:
t = nu2.Time;
[~, idx] = unique(year(t));
set(gca, 'Ticks', t(idx));
UNTESTED due to lack of input data. And I assume it is not working!
But the idea is: Get the wanted datetime values and set them as Ticks.
John BG
on 17 Jan 2018
Jan Simon, the lack of data shouldn't be a problem, just try for instance
n_samples=3521
nu2=randi([1 10],1,n_samples)
John BG
See Also
Categories
Find more on Time Series Events in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!