Plot a mean of ten lines of different resolution

6 views (last 30 days)
Robert on 9 Jul 2023
Commented: Star Strider on 10 Jul 2023
Hello all,
I would like to plot the mean of ten lines. Each line plots the data from a different longitude and latitude against a timeslice. The data (mean annual temperature over the past 120,000 years) only covers temperatures on land, and as such, some timeslices have no corresponding temperature data for the years in which they were submerged.
The data dimensions are as follows:
Longitude: 720x1
Latitude: 300x1
Month: 12x1
Year: 72x1
Monthly temperature: 720x300x12x72
Can anyone advise on how to plot the mean of these ten timeslices? That is to say, the mean temperature over the past 120,000 years across the ten coordinate points plotted. I am very new to MATLAB and programming generally so help would be greatly appreciated.
my_year = -10000;
my_month = 6;
my_longitude = 11.2980;
my_latitude = 62.4342;
[~,lonID] = min(abs(longitude - my_longitude));
[~,latID] = min(abs(latitude - my_latitude));
[~,yearID] = min(abs(years - my_year));
mean_annual_temperature = mean(temperature,3);
plot(years, squeeze(mean_annual_temperature(lonID, latID, :)), 'Marker', 'none', 'Color', '#fff100');
title(['Mean annual temperature time series, 60N to 65N']);
xlabel('Year');
ylabel('Temperature °C');
MarKf on 9 Jul 2023
Edited: MarKf on 9 Jul 2023
Still unclear what you need the mean of and what do you need to plot from your description. What are the 10 lines in the 120,000 values?
I assume from the plot and the code that you want the annual average, that is averaging all the months in the years so to have a single mean value per year, to be clear, 72 yearly scores for each of the 720 longs times 300 lats. That would be 216000*72 average values, but I'm guessing some are missing so that's how you get 120000? (also misleading to call them 120,000 years, having 72 years of recording is impressive but hundreds of thousands? a strage way to put it).
Again from the plot, the missing values seem to be NaNs already, that'd be conveninent but do check that. In that case mean_annual = mean(temp,3,"omitnan") will ignore the missing values, otherwise just temp(indecesofmissing) = nan first, so that'd take care of that.
You're then finding an index of lats and longs (and also a yearID, but that's ignored) so I'm guessing that's how you choose those 10 annual vectors, there is no way for us to know without having the full code, variables and data. When you select those data, subsetemp = squeeze(mean_annual_temperature(lonID, latID, :) would work if the indeces lonID, latID were 2 ranges, so I assume the variables longitude and latitude are. And there's the rub for having "different resolutions of longitude and latitude against a timeslice", but again not sure what you need there.
Robert on 9 Jul 2023
Sorry, again new to MATLAB. The dataset covers 72 timeslices over the last 120,000 years from a palaeoclimate simulation (every 2,000 years except for the latest 22,000 years for which there is a resolution of every 1,000 years). The simulation has global coverage but as I am only seeking to analyse data for those parts of Europe not generally covered in icesheets I have limited the area to latitudes 35 to 65 and longitudes -10 to 50.
As temperatures would vary so much by topography even within similar latitudes, I elected to use a random coordinate generator (online) to output ten sets of coordinates per five degrees of latitude with the rule that none would be within 200km of eachother (see image). The image attached is a plot of the temperature for the ten randomly generated points over the 72 timeslices. What I wished to do was add a final line displaying a mean temperature for the entirety of that five degrees of latitude (though still between longitudes -10 and 50). I don't know how this could be done from the raw data as it requires coordinates to be inputted to produce temperature readings. Consequently, I assumed the mean would need to be the mean of the ten random sets of coordinates. I hope that makes sense. I know I am not describing it very well, but this really is all awfully new to me.
The code I provided in the question was the only code I have used, besides the ncread function to read in the data in the first place. I have since cut out some of the superfluous code such that it now reads as follows:
my_longitude = 31.7109;
my_latitude = 62.0342;
[~,lonID] = min(abs(longitude - my_longitude));
[~,latID] = min(abs(latitude - my_latitude));
mean_annual_temperature = mean(temperature,3);
plot(years, squeeze(mean_annual_temperature(lonID, latID, :)), 'Marker', 'none', 'Color', '#fff100');
title(['Mean annual temperature time series, 60N to 65N']);
xlabel('Year (10ka)');
ylabel('Temperature °C');
After this, I have been using the 'hold on' function and then been repeating the code for each set of coordinates viz.
hold on
my_longitude = 34.9305;
my_latitude = 64.9094;
[~,lonID] = min(abs(longitude - my_longitude));
[~,latID] = min(abs(latitude - my_latitude));
mean_annual_temperature = mean(temperature,3);
plot(years, squeeze(mean_annual_temperature(lonID, latID, :)), 'Marker', 'none', 'Color', '#ff8c00');

Star Strider on 9 Jul 2023
It would help to have the actual data.
The missing data must be NaN values, since if they were simply blank, they would throw an error using the posted code. The result of ‘squeeze(mean_annual_temperature(lonID, latID, :))’ is therefore a 2D matrix, although I cannot determine its size relative to ‘years’ since plot corrects for that.
Guessing at the data, perhaps something like this —
mean_annual_temperature = randn(10, 72); % Create Data
mean_annual_temperature(5,[1:5 30:35 67:72]) = NaN; % Insert Some 'NaN' Values In One Row
years = 1:72; % Create Data
A = [years; mean_annual_temperature] % Concatenate MAtrices
A = 11×72
1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 24.0000 25.0000 26.0000 27.0000 28.0000 29.0000 30.0000 -0.5411 -0.2815 1.0491 -1.6423 2.1098 1.6537 0.4762 2.0208 -0.5480 -0.3442 0.3323 -0.8276 -0.6295 1.0037 1.7795 1.2000 0.0774 1.6986 0.9332 0.4624 -0.1027 0.5142 -1.8523 -1.6349 -1.4737 0.6622 1.0846 0.1649 0.6325 -1.2057 -1.0054 0.6366 -0.9178 0.4337 0.6949 -1.7411 -0.3371 -1.3497 0.1201 -0.5295 0.2605 -0.3146 -0.2346 0.5556 0.7186 -0.9240 -0.1993 0.4710 1.4087 0.8780 -1.5684 0.6322 -1.2419 -0.7496 0.8837 -1.1482 2.2219 1.6758 -0.7045 -0.3722 0.1136 -0.0925 -0.1438 0.1713 0.4869 -0.1721 -1.9443 -0.2211 0.9828 -1.6542 0.6495 2.4467 -0.0475 -0.9288 -1.0449 1.5306 1.1406 0.7564 1.0304 0.5020 -0.9871 1.2289 0.9241 -0.6455 -0.1782 -1.1711 0.8850 0.3774 1.2468 0.7507 1.7575 1.5207 0.2616 -0.2608 -0.1276 0.9961 1.7219 0.1804 -0.2159 -0.7337 1.2809 1.3715 -0.0790 -0.2903 0.7787 1.3648 0.6253 0.2691 1.0305 0.9526 -0.1336 0.1418 -2.1785 -0.9253 -1.1874 -0.1016 0.1417 0.7380 -1.4048 -0.6412 NaN NaN NaN NaN NaN 2.5600 -0.4187 0.2515 -1.1774 1.1921 0.0762 -0.5691 0.2553 -0.7648 -0.7495 -0.5558 0.3327 -0.5510 0.1954 -0.3573 0.6896 1.5520 -1.9564 -1.5962 -1.4834 0.2716 0.9360 0.8312 -1.2839 NaN 0.7411 1.2922 0.2373 -0.6004 -1.4177 0.3602 0.8799 -1.1416 -0.8418 -0.0143 0.1472 -0.5124 1.2289 0.4280 -1.4072 -0.9609 1.3112 0.5484 0.8923 0.9473 0.2731 -1.2310 0.3174 -0.3024 -0.1986 2.2675 -0.5148 1.3039 1.3289 1.4054 0.0809 -0.4823 1.6888 -0.5762 0.1305 0.0925 0.6768 -0.3189 -0.8624 -1.2713 0.2825 -0.8371 -0.4500 -0.4663 -0.5002 -0.8410 0.0627 -0.7790 -0.1689 -0.8123 -0.1346 0.3743 0.3414 0.8541 1.0799 1.4315 0.5249 -0.1618 0.7157 -1.0191 0.7756 0.3965 -0.0901 -1.9013 -0.0282 0.4677 1.0814 -0.6354 -0.6108 1.2923 0.1929 -0.2663 -0.3312 -0.3346 -1.3464 -0.6880 0.9257 0.5566 -0.3718 0.1646 -0.1353 -0.4565 0.5285 0.1605 0.0936 -0.7124 -0.7214 -0.6197 0.0074 -1.3784 0.4037 0.0719 1.1228 -1.2194 0.6413 -0.7957 0.3585 0.2729 -0.8332 0.8570 2.8250 0.6536 0.1170 1.7289 0.9317 -0.5336 -1.7100 0.0384 0.7644 0.7899 1.0520 -1.1361 -1.6468 -1.2941 1.8891 0.7357 0.4758 -0.8837 0.2715 -1.3944
NaNidx = any(isnan(A),1) % Determine 'NaN' Columns
NaNidx = 1×72 logical array
Columns 1 through 49 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Columns 50 through 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
A = rmmissing(A, 2) % Remove Missing Values Columns
A = 11×55
6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 24.0000 25.0000 26.0000 27.0000 28.0000 29.0000 36.0000 37.0000 38.0000 39.0000 40.0000 41.0000 1.6537 0.4762 2.0208 -0.5480 -0.3442 0.3323 -0.8276 -0.6295 1.0037 1.7795 1.2000 0.0774 1.6986 0.9332 0.4624 -0.1027 0.5142 -1.8523 -1.6349 -1.4737 0.6622 1.0846 0.1649 0.6325 -0.6346 -1.8883 -0.9102 -0.7969 -2.7951 -1.1729 -1.7411 -0.3371 -1.3497 0.1201 -0.5295 0.2605 -0.3146 -0.2346 0.5556 0.7186 -0.9240 -0.1993 0.4710 1.4087 0.8780 -1.5684 0.6322 -1.2419 -0.7496 0.8837 -1.1482 2.2219 1.6758 -0.7045 -1.2104 -1.1930 -1.1528 -0.5900 0.3916 -2.2763 -0.1721 -1.9443 -0.2211 0.9828 -1.6542 0.6495 2.4467 -0.0475 -0.9288 -1.0449 1.5306 1.1406 0.7564 1.0304 0.5020 -0.9871 1.2289 0.9241 -0.6455 -0.1782 -1.1711 0.8850 0.3774 1.2468 -1.7037 1.4887 1.4091 0.2819 0.7183 -0.2286 0.9961 1.7219 0.1804 -0.2159 -0.7337 1.2809 1.3715 -0.0790 -0.2903 0.7787 1.3648 0.6253 0.2691 1.0305 0.9526 -0.1336 0.1418 -2.1785 -0.9253 -1.1874 -0.1016 0.1417 0.7380 -1.4048 0.6505 0.7621 -1.5573 0.8716 1.9005 2.3778 2.5600 -0.4187 0.2515 -1.1774 1.1921 0.0762 -0.5691 0.2553 -0.7648 -0.7495 -0.5558 0.3327 -0.5510 0.1954 -0.3573 0.6896 1.5520 -1.9564 -1.5962 -1.4834 0.2716 0.9360 0.8312 -1.2839 0.0489 -0.2204 1.1651 0.9799 -1.0178 1.3577 0.3602 0.8799 -1.1416 -0.8418 -0.0143 0.1472 -0.5124 1.2289 0.4280 -1.4072 -0.9609 1.3112 0.5484 0.8923 0.9473 0.2731 -1.2310 0.3174 -0.3024 -0.1986 2.2675 -0.5148 1.3039 1.3289 -0.9200 2.8640 0.1464 -0.4054 -1.5230 0.2206 0.0925 0.6768 -0.3189 -0.8624 -1.2713 0.2825 -0.8371 -0.4500 -0.4663 -0.5002 -0.8410 0.0627 -0.7790 -0.1689 -0.8123 -0.1346 0.3743 0.3414 0.8541 1.0799 1.4315 0.5249 -0.1618 0.7157 0.5353 1.1854 1.0517 0.2672 -0.0787 2.1001 0.4677 1.0814 -0.6354 -0.6108 1.2923 0.1929 -0.2663 -0.3312 -0.3346 -1.3464 -0.6880 0.9257 0.5566 -0.3718 0.1646 -0.1353 -0.4565 0.5285 0.1605 0.0936 -0.7124 -0.7214 -0.6197 0.0074 -1.7194 1.3012 0.1291 -1.3113 0.0739 0.3585 -0.7957 0.3585 0.2729 -0.8332 0.8570 2.8250 0.6536 0.1170 1.7289 0.9317 -0.5336 -1.7100 0.0384 0.7644 0.7899 1.0520 -1.1361 -1.6468 -1.2941 1.8891 0.7357 0.4758 -0.8837 0.2715 -0.4024 1.2618 -0.0973 0.2869 0.4551 -0.0912
Ayears = A(1,:) % Recover Vector
Ayears = 1×55
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 36 37 38 39 40 41
Amean = mean(A(2:end,:)) % Mean Of Remaining Columns
Amean = 1×55
0.3939 0.1929 -0.1931 -0.2693 -0.2191 0.3811 0.2106 0.1184 0.0441 -0.0865 -0.1509 0.2900 0.3111 0.6957 0.1766 -0.2510 0.1573 -0.7657 -0.6470 -0.0800 0.3188 0.5565 0.4261 0.0517 -0.4467 0.5210 0.0602 -0.1574 -0.0955 0.1871
B = NaN(size(years)); % Create 'NaN' Vector
B(~NaNidx) = Amean % Assign Mean Values To 'Non-NaN' Index Positions
B = 1×72
NaN NaN NaN NaN NaN 0.3939 0.1929 -0.1931 -0.2693 -0.2191 0.3811 0.2106 0.1184 0.0441 -0.0865 -0.1509 0.2900 0.3111 0.6957 0.1766 -0.2510 0.1573 -0.7657 -0.6470 -0.0800 0.3188 0.5565 0.4261 0.0517 NaN
figure
hp1 = plot(years, mean_annual_temperature, 'DisplayName','Temperature MAtrix');
hold on
hp2 = plot(years, B, '-k', 'LineWidth',2, 'DisplayName','Mean Temperatures');
hold off
title(['Mean annual temperature time series, 60N to 65N']);
xlabel('Year');
ylabel('Temperature °C');
legend([hp1(1) hp2], 'Location','best')
This plots only the data for the years in which no data are missing. I believe this is preferable to using the mean 'omitmissing' flag, since this approach only uses data from years in which all data are present.
.
Robert on 10 Jul 2023
Thank you. For some reason they are all coming out black for me. I have, however, been enough of a nuisance to you I'm sure so I really don't think I can ask you to keep assisting me. Thanks ever so much for all your help.
Star Strider on 10 Jul 2023
My pleasure!
The colours are as you defined them.
To see that the idea actually works experiment with:
mycolors = colormap(turbo(10));
.

MarKf on 9 Jul 2023
I see, this is overly complicated. Not as in complex or difficult, as in made needlessly overly complicated.
Let's just say you have 72 timepoints (or slices). You average the months as above (which is a point that is now unclear to me since we are talking about geological eras but whatever) and get 72 timepoints. I can see you already can plot those timepoints with the right scale with plot(years, mean_annual) so no probl. I'd say you'd be more interested in having the mean data points even if some locations or times are missing, so likely just 'omitnan' as I mention previously for now, rather than rmmissing as in the answer above.
In the map image you then have 10 random coordinates for each of 6 latitude ranges of 5 degrees, from south to north EU. So in this case you have 60 locations. Each location has a lat and a longit obvs. You can have a matrix of 60*2 of lats and a longits keeping track of the location and then a 60*72 mat of locations*timepoints vectors (timeseries). I'm unsure how you get the raw data then, but I assume you can easily create these 2 variable from what you got so far.
Then you just select the timeseries you want to average and/or plot based on the geograhical range of your choice. Maybe this code snippet can give you an idea.
lats = 35:5:65; longs = [-10 50]; lpoints = 10;
yearsn = 72; years = [-120000:2000:-22000 -19000:1000:2000];
loc = [];
for il = 1:numel(lats)-1
random_lats = (lats(il+1)-lats(il)).*rand(lpoints,1) + lats(il); %just a quickly randomly generated example
random_longs = (longs(2)-longs(1)).*rand(lpoints,1) + longs(1); %likely not to have the 200km apart requirement
loc = [loc;random_lats,random_longs]; %in this case they would be already ordered in groups of 5°
end
mean_annual_temp = randn(size(loc,1), yearsn); % random mean annual temperature data
mean_annual_temp(randi([1 numel(mean_annual_temp)],1,100)) = NaN; %add missing
%select locs based on lat (even if already ordered in groups of 5°, just in case)
range_lat = [43 48]; % you could also do this in a loop as above with like for il = 1:numel(lats)-1, [lats(il) lats(il+1)]
loc_idx = loc(:,1)>=range_lat(1) & loc(:,1)<range_lat(2);
subsetmat = mean_annual_temp(loc_idx,:); % you could selct a time range with (:,time_idx); as well
subsetmean = mean(subsetmat,'omitnan');
%then same as above
figure
plot(years, subsetmat); %already plots all with diff colors
hold on
plot(years, subsetmean, '-k', 'LineWidth', 3);
hold off
title(sprintf('Mean annual temperature time series, %dN to %dN',range_lat));
xlabel('Year');
ylabel('Temperature °C');

Categories

Find more on Geographic Plots in Help Center and File Exchange

R2023a

Community Treasure Hunt

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

Start Hunting!