how to make a contour with time variable on x-axis

12 次查看(过去 30 天)
I have a data that contains values of Altitude,Temperature and Time for a single day. Time starts at 00:09:27 and ends on 23:41:57. The altitude varies throughout the day starting from 0 going until around 250 and coming back to 0 and again to 250 and so on. There is certain period within this time that I dont have any data. I want to interpolate the values for it. When I use
contourf(data.Time,data.Altitude,data.Temp)
it gives me an error saying
Input arguments must be numeric or objects which can be converted to double.
How can I overcome this problem? Essentially I want time in x-axis and Temp in y axis and a color bar that indicates the temperature.

回答(2 个)

dpb
dpb 2017-10-4
If contourf isn't yet datetime aware, convert to datenum instead which are just a double. Then you'll have to use datetick on the x-axis to scale as time but should work.
  3 个评论
dpb
dpb 2017-10-5
Well, that's nothing to do with whether X is/is not date but that you don't have commensurate data Z to go with your X,Y vectors. From the documentation for coutourf
...
contourf(X,Y,Z), ... draw[s] filled contour plots of Z using X and Y
to determine the x and y values.
If X and Y are vectors, then length(X) must equal size(Z,2) and
length(Y) must equal the number of rows in size(Z,1).
The vectors must be strictly increasing or strictly decreasing
and cannot contain any repeated values.
However, you've got another problem it would seem that your Y (altitude) isn't strictly monotonic but cyclic. In that case you'd have to have X,Y as arrays and "plaid" for contourf to work.
Need more details on the actual data you've got to tell for sure but looks likely you haven't enough in the correct locations to satisfy the requirements to use contourf
dpb
dpb 2017-10-5
Altitude Temp Time
0 15.7 0:09:27
0.8 15.9 0:09:30
6.3 15.7 0:09:34
6.7 15.7 0:09:38
...
18.5 15.7 0:10:02
22.4 15.7 0:10:06
28.3 15.8 0:10:10
33.4 15.8 0:10:20
34.2 15.9 0:10:24
...
139.5 16.6 0:14:58
141.1 16.6 0:15:01
141.1 16.9 0:15:05
145.9 16.7 0:15:08
151.5 16.8 0:15:15
...
210.2 16.6 0:17:54
211.8 16.7 0:18:01
211.8 16.7 0:18:04
214.3 16.7 0:18:08
217.1 16.7 0:18:11
217.1 16.7 0:18:15
220.3 16.7 0:18:18
223.5 16.6 0:18:22
226.4 16.7 0:18:26
...
242.5 16.5 0:19:21
245.8 16.7 0:19:24
248.2 16.6 0:19:28
248.2 16.6 0:19:42
249 16.4 0:19:45
249.8 16.7 0:19:49
251.1 16.5 0:19:56
252.3 16.5 0:20:03
253.1 16.5 0:20:07
253.1 16.5 0:20:10
253.5 16.5 0:20:33
253.5 16.5 0:20:33
251.1 16.6 0:20:37
251.1 16.6 0:20:41
...
192.5 16.7 0:29:37
190.1 16.6 0:29:40
...
"The vectors must be strictly increasing or strictly decreasing and cannot contain any repeated values."
Your altitude measurements don't have enough resolution to prevent condition a) several times and are more-or less sinusoidal rather than monotonic.
a) can be handled by finding locations of duplicates and offsetting 2nd (and any subsequent) identical readings with an epsilon that is sufficient to be nonzero difference between subsequent readings but small enough as to be of no material change numerically. You may find the builtin function eps useful in this regard.
You'll have to rearrange the altitude column by sections that are strictly increasing/decreasing -- I'm not positive whether you'll have to resort the order to make all columns in the array the same order or whether contourf is capable of handling both directions as long as they're monotonic; you'll just have to 'spearmint on that one.
Note you will have to make all columns the same length; this may require filling in with NaN some shorter columns to create rectangular array.
When you do this, then the above syntax for X,Y as vectors is no longer applicable as they're then arrays rather than vectors.
Alternatively, sort the two keeping the index of the temperature location to reconstruct the proper value with the proper set of altitude/time coordinates.

请先登录,再进行评论。


John
John 2024-6-27
I have hacked a version of contour (lacking the full suite of input options) that uses contourc to find the contour lines after first converting any datetime coordinate to datenum. Then, after finding the contour lines convert them back to datetime to draw. The trick is knows how to decode the output from contourc, which I have documented in the code below. I hope Mathworks will do this more elegantly. I note that surf already supports datetime coordinate inputs, but not contour.
function [CVAL,HAN] = contourd(xd,yd,dd,V)
% CONTOURD(XD,YD,DD)
% CONTOURD(XD,YD,DD,V)
% Contour plot allowing for XD or YD as DATETIME - until Mathworks fixes it
% John Wilkin - jwilkin@rutgers.edu June 2024 at hanse-ias.de
datenum_to_datetime_x = false;
if isdatetime(xd)
datenum_to_datetime_x = true;
xd = convertTo(xd,'datenum');
end
datenum_to_datetime_y = false;
if isdatetime(yd)
datenum_to_datetime_y = true;
yd = convertTo(yd,'datenum');
end
% contourc gets the contours but does not plot them
% Excuse the inelegant handling of input options
if nargin==4
c = contourc(xd,yd,dd,V);
else
c = contourc(xd,yd,dd);
end
% C is a 2-row matrix with the contour coordinates in XD,YD space. All
% contours are strung together in a vector broken by a segment count.
% C(1,1) is the first contour value
% C(2,1) is the number of points in the first contour
% There another set ... next contour value and number of points, etc.
x = c(1,:);
y = c(2,:);
nval = y(1); % number of points in first contour
ks = 2; % start index of first contour
kount = 1; % counter
while 1 % plot each contour segment and then go to next
cval(kount) = x(ks-1); % contour value
ke = ks+(nval-1); % end index of this contour
xp = x(ks:ke); % x of this contour
yp = y(ks:ke); % y of this contour
% convert back to datetime
if datenum_to_datetime_x
xp = datetime(xp,'ConvertFrom','datenum');
end
if datenum_to_datetime_y
yp = datetime(yp,'ConvertFrom','datenum');
end
% plot
han(kount) = plot(xp,yp);
hold on
% advance to next contour
ks = ke+2;
try
nval = y(ke+1); % number of points in next contour
catch
% reached the end
break
end
kount = kount+1;
end
hold off
% assign common color to the same contour values
[cv,ia] = unique(cval);
for k=1:length(ia)
set(han(cval==cv(k)),'Color',han(k).Color)
end
if nargout > 0
CVAL = cval;
end
if nargout > 1
HAN = han;
end

类别

Help CenterFile Exchange 中查找有关 Lighting, Transparency, and Shading 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by