gnuplot overlay same time different day plots? - date

I have two data files of two days and same time
date1data.csv
2018.02.03.18:23,4
2018.02.03.19:23,22
2018.02.03.20:23,12
2018.02.03.21:23,3
2018.02.03.22:23,16
date2data.csv
2018.02.04.18:23,1
2018.02.04.19:23,5
2018.02.04.20:23,22
2018.02.04.21:23,5
2018.02.04.22:23,14
If I plot them I get this plot where the data is plotted one day after another.
How can I plot them with respect to the time only and not the date so that they overlay at the same time? Is this possible? I dont want to plot them in multiple windows.
Thats the code I used for plotting:
set datafile separator ","
set terminal pngcairo size 500,200 enhanced font 'Verdana,10' linewidth 1
set output 'test.png'
set xdata time
set timefmt "%Y.%m.%d.%H:%M"
set format x "%H:%M"
plot 'date1data.csv' using 1:2 w lines lw 2 t "day1", 'date2data.csv' using 1:2 w lines lw 2 t "day2"

You can replace using 1:2 with a function that drops the date part of the time string that is column 1:
set timefmt "%H:%M"
f(v) = substr(stringcolumn(v),12,16)
plot 'date1data.csv' using (f(1)):2 w lines lw 2 t "day1",\
'date2data.csv' using (f(1)):2 w lines lw 2 t "day2"

Here is a solution that uses the stats command to find the earliest time in the two data files, and shifts the times of the second file so that aligns with the earliest time in the first file. We have to work around a limitations of the stats command because it does not work in timedata mode, but we can work around that by doing the time-to-seconds conversion ourselves:
set datafile separator ","
fmt = "%Y.%m.%d.%H:%M"
stats "date1data.csv" u (strptime(fmt,strcol(1)))
t1min = STATS_min
stats "date2data.csv" u (strptime(fmt,strcol(1)))
t2min = STATS_min
set xdata time
set format x "%H:%M"
plot 'date1data.csv' using (strptime(fmt,strcol(1))):2 w lines lw 2 t "day1", \
'date2data.csv' using (strptime(fmt,strcol(1))-t2min+t1min):2 w lines lw 2 t "day2"
This approach has the advantage that it should work even if the data crosses date boundaries.

You can just remove the date part from your data by subtracting midnight:
t(x) = x - 24*3600*(floor(x/(24*3600))
plot dataf1 us (t($1)):2, dataf2 us (t($1)):s
This actually works 100% correctly because unix time ignores leap seconds, your computer clock just adjusts itself when one occors.

Related

gnuplot scatter plot selecting data on range of value in 3rd Column

In a Windows 7 environment, I need to do a gnuplot scatter plot of 2 columns selecting data based on a range of values in a 3rd column. I know how to do it by creating separate data files for each range, but is it possible to do it by filtering on the data value in a 3rd column without awk
Thanks
plot "<awk '{if($3>=11 && $3<=19) print $0}' plot.dat " using 1:2 with points
warning: Skipping data file with no valid points
I Presume the error is because I don't have awk in windows7 envirenment
There are (should be) many examples of filtering data with gnuplot here on StackOverflow, however, mostly combined with another issue. So, whenever I'm trying to search for a really good and clear example, it takes more time for searching than to simply write down the line.
You definitely don't need awk!
Attention: Filtered data will not be connected in a line plot. So, in case you want to plot connected filtered lines, e.g. with lines or with linespoints you need to prepend an extra line. I assume you have gnuplot>=5.0.
For older gnuplot versions you can check this workaround.
The following will plot column 1 versus column 2, but only if column 3 is in the range 11 to 19.
set datafile missing NaN
plot "myData.dat" u 1:($3>=11 && $3<=19 ? $2: NaN) w linespoints

Resample time based column array as per sampling time in Matlab

I need to run a simulation with sample time of
tsample = 0.01 ; % seconds
I have a table such as below
I need to resample each column in input table such that value of the input Time vector gets equally spaced based on tsample values.
For the [Time] column I achieved this by following code
simTime = max(tests.(test_names{i}).Times); % Seconds
% Interpolate the time and frequency values as per sample time
numSteps = simTime/tsample;
time = tsample * [0:(numSteps-1)]';
What I need to do now is resize the frequency (f) values such that it shall be filled with previous values until a new value is found in column;
Time
f
0
50
....
50
4.99
50
5.00
49.65
....
49.65
19.99
49.65
20.00
49.80
I am confused whether I should use fillmissing or resample or interp1.
The examples I am following for these seem kind of different than what I wish to achieve here.
Any help would be really appreciated.
Thank you.
Ok,
I tried experimenting with more examples for interp1 and this solved my issue.
freq = interp1(tests.Times, tests.fHz, time, 'previous');
I was earlier unaware of the 'previous' option
Should have searched the documentation more extensively.

Plotting with respect to minutes as formatted time (min.sec)

I'm trying to plot some data with respect to minutes instead of seconds in Matlab as formatted time, i.e. min.sec.
I have real time data streaming in where with every sample received, its time in seconds is also sent. I then plot them with respect to time. Now, since my session is around 15 minutes long, I can't be plotting with respect to time. Therefore I wanted to plot it with respect to time (min.sec). I tried dividing the received time by 60 but this gives me minutes with 100 subdivisions instead of 60 (the minutes increment after 0.9999 instead of 0.59). How do I convert it so that I'm able to plot with respect to time in minutes?
Here is what I mean by 0.99 fractions of a minute instead of 0.59. A normal minute has 60 divisions not 100.
EDIT:
I tried m7913d's suggestions and here is what I got.
first I plot the signal with respect to time in seconds without changing the ticks ( A normal plot(t,v))
The I added datetick('x', 'mm:ss'); to the plot (Xtick format is not supported in Matlab 2015b)
Here is a screenshot of the results
The time in seconds was up to 80 seconds, when translated into minutes, it should give me 1 minutes and 20 seconds as the maximum x axis limit. But this is not the case. I tried to construct a t vector (i.e like t=0:seconds(3):minutes(3)) but I couldn't link it to my seconds vector which will be constantly updating as new samples are received from the serial port.
Thanks
You can use xtickformat to specify the desired format of your x labels as follows:
% generate a random signal (in seconds)
t = 0:5:15*60;
y = rand(size(t));
plot(seconds(t),y) % plot your signal, making it explicit that the t is expressed in seconds
xtickformat('mm:ss') % specify the desired format of the x labels
Note that I used the seconds methods, which returns a duration object, to indicate to Matlab that t is expressed in seconds.
The output of the above script is (the right image is a zoomed version of the left image):
Pre R2016b
One can use datetime instead of xtickformat as follows:
datetimes = datetime(0,0,0,0,0,t); % convert seconds to datetime
plot(datetimes,y)
datetick('x', 'MM:SS'); % set the x tick format (Note that you should now use capital M and S in the format string
xlim([min(datetimes) max(datetimes)])

How to draw time based graphs using ios-charts

I'm trying to draw a temperature graph using iso-charts where the x axis data would be set from a server timestamp but the labels would be readable text.
For instance the graph x-axis label would start at Monday 00:00 and end Tuesday 12pm but the LineChartDataSet would be a collection of temperature (y-axis) and timestamps for the x
To display the timestamp I have a custom valueFormatter set as follow (which works great)
lineChartView.xAxis.valueFormatter = timestampXAxisFormatter() //converts timestamp to Date string
My question: The LineChartDataSet seems to be indexed based which is causing some trouble: if I have 4 data points such as (9am, 10), (9:15am, 11), (12pm, 15), (1pm, 16) the 4 points are set in the chart at regular intervals (I was expecting 2 points to be on the left side of the graph and then last 2 points on the right side) - Is there a way to have a data set that is based on the x value instead of the index?
I saw ChartData has an init that takes an array of NSObjects but then it converts it to Strings...Thanks in advance for any suggestions you may have!
There is no good way to solve it, as you figured out the x axis is index based.
You have two options:
insert many x values between each real x value, like between 9:00 and 9:15, you manually insert 9:01, 9:02, ..., 9:14, but don't add any entry at these values, just ignore it and continue. ios-charts will skip if no entry found and go to next. This will works fine, if you don't have a large number of values to insert. I tried ~1000 values, the performance is acceptable.
you create your own chart, using two y axis, one as x axis and one as y axis, so the distances to 0 point are calculated by value. However this requires you understand the ios-chart logic deeply. If you succeed, you are more than welcome to file a PR.

labeling x-axis with cell array

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))