matlab代码
读取气温nc文件,并整理成逐年逐站点平均气温或者出气温分布图 本帖最后由 歌者文明清理员 于 2023-4-17 09:34 编辑以下是 MATLAB 读取气温 nc 文件并生成逐年逐站点平均气温的代码示例:
% 指定 nc 文件路径
filename = 'path/to/temperature_file.nc';
% 读取 nc 文件中某一个变量(这里假设为气温变量)
temp = ncread(filename, 'temperature');
% 获取参考时间的起始日期
ref_date = ncreadatt(filename, '/', 'units');
ref_date_str = extractAfter(ref_date, 'since ');
ref_date_val = datetime(ref_date_str);
% 读取站点的经纬度信息和站名
lat = ncread(filename, 'latitude');
lon = ncread(filename, 'longitude');
station_names = ncread(filename, 'station_name');
% 计算每个站点每年的平均气温
= size(temp);
annual_mean_temp = zeros(n_stations, n_years);
for i = 1:n_stations
for j = 1:n_years
year_temp = temp(i, (12*(j-1)+1):(12*j)); % 提取一年中的气温数据
annual_mean_temp(i,j) = mean(year_temp(year_temp > -999)); % 计算有效气温的平均值
end
end
% 生成逐年逐站点平均气温的热力图(需要安装 Mapping Toolbox)
figure
worldmap('World')
load('coastlines')
plotm(coastlat, coastlon)
cmap = jet(256);
colormap(cmap)
title('Annual Mean Temperature')
for i = 1:n_stations
lat_idx = find(abs(lat(i)-coastlat) == min(abs(lat(i)-coastlat)));
lon_idx = find(abs(lon(i)-coastlon) == min(abs(lon(i)-coastlon)));
if ~isempty(lat_idx) && ~isempty(lon_idx)
color_idx = round((annual_mean_temp(i,1)-min(annual_mean_temp(:)))/(max(annual_mean_temp(:))-min(annual_mean_temp(:)))*255)+1; % 计算颜色索引
scatterm(lat(i), lon(i), 10, cmap(color_idx,:), 'filled', 'MarkerEdgeColor', 'k')
textm(lat(i), lon(i), station_names(i,:), 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle')
end
end
如果你需要绘制每个站点的逐年气温分布图,可以使用 boxplot 函数:
% 绘制逐年逐站点气温分布箱线图
figure
for i = 1:n_stations
subplot(ceil(sqrt(n_stations)),ceil(sqrt(n_stations)),i);
boxplot(squeeze(temp(i,:,:)), 'Labels', (ref_date_val.Year+1):(ref_date_val.Year+n_years), 'Whisker', 2.3);
title(station_names(i, :))
end
suptitle('Station Temperature Distribution')
如果你需要绘制整个区域内所有站点的气温分布图,可以使用 histogram2 函数:
% 绘制整个区域内所有站点的气温分布图(需要安装 Statistics and Machine Learning Toolbox)
figure
histogram2(lon(:), lat(:), 'BinMethod', 'fd', 'FaceColor', 'flat')
colormap(jet)
colorbar
xlabel('Longitude')
ylabel('Latitude')
zlabel('Temperature')
title('Temperature Distribution')
这是生成站点温度分布可以使用 scatterm 函数:
% 绘制整个区域内所有站点的气温散点图(需要安装 Mapping Toolbox)
figure
worldmap('World')
load('coastlines')
plotm(coastlat, coastlon)
cmap = jet(256);
colormap(cmap)
title('Temperature Distribution')
for i = 1:n_stations
lat_idx = find(abs(lat(i)-coastlat) == min(abs(lat(i)-coastlat)));
lon_idx = find(abs(lon(i)-coastlon) == min(abs(lon(i)-coastlon)));
if ~isempty(lat_idx) && ~isempty(lon_idx)
color_idx = round((annual_mean_temp(i,1)-min(annual_mean_temp(:)))/(max(annual_mean_temp(:))-min(annual_mean_temp(:)))*255)+1; % 计算颜色索引
scatterm(lat(i), lon(i), 10, cmap(color_idx,:), 'filled', 'MarkerEdgeColor', 'k')
textm(lat(i), lon(i), station_names(i,:), 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle')
end
end
请注意,这些示例代码可能需要根据你的实际数据情况进行一定的修改。 歌者文明清理员 发表于 2023-4-17 09:31
以下是 MATLAB 读取气温 nc 文件并生成逐年逐站点平均气温的代码示例:
大佬,啥意思,那个nc好像是二进制的,打开乱码 歌者文明清理员 发表于 2023-4-17 09:31
以下是 MATLAB 读取气温 nc 文件并生成逐年逐站点平均气温的代码示例:
嗷嗷,好的,谢谢大佬,我试试去 根据您的要求,下面是一个MATLAB代码示例,用于读取气温数据的NetCDF文件,并按年和站点计算平均气温以及生成气温分布图。
% 加载nc文件
filename = 'temperature_data.nc';
temp_var = 'temperature'; % 根据您的nc文件中的变量名进行替换
% 获取时间、站点和气温信息
time = ncread(filename, 'time');
station = ncread(filename, 'station');
temperature = ncread(filename, temp_var);
% 计算逐年逐站点平均气温
years = unique(floor(time/365)); % 假设时间单位为天数
num_years = length(years);
num_stations = length(station);
annual_avg_temp = zeros(num_years, num_stations);
for i = 1:num_years
year = years(i);
start_day = year * 365 + 1;
end_day = start_day + 364;
annual_avg_temp(i, :) = mean(temperature(start_day:end_day, :), 1);
end
% 输出结果
disp('逐年逐站点平均气温:');
disp(annual_avg_temp);
% 生成气温分布图
= meshgrid(1:num_stations, years);
figure;
contourf(X, Y, annual_avg_temp);
colorbar;
xlabel('Station ID');
ylabel('Year');
title('Annual Average Temperature by Station');
请将filename变量更改为您的NetCDF文件名,并根据您的数据集确保temp_var变量名称正确。这个代码示例假设时间单位是天数,如果您的数据集时间单位不同,请相应地调整时间计算。
如果您需要进一步的帮助,请随时提问。 聆風祈 发表于 2023-4-17 09:34
大佬,啥意思,那个nc好像是二进制的,打开乱码
NC 文件(netCDF 文件)是一种二进制文件格式,不能直接使用文本编辑器打开查看。你需要使用专门的工具或编程语言进行读取和处理。
在 MATLAB 中,你可以使用 ncread 函数读取 nc 文件中的变量,并使用其他函数操作它们。如果你仍然只是想查看 NC 文件内容,请考虑使用如下工具:
[*]Panoply 可以用来快速查看和分析 nc 文件。
[*]ncdump 命令行工具可以将 nc 文件转换成 ASCII 格式,方便你阅读。
还有其他很多处理和可视化 NC 文件的方式和工具,具体取决于你的需求和技术水平。 isdkz 发表于 2023-4-17 09:35
根据您的要求,下面是一个MATLAB代码示例,用于读取气温数据的NetCDF文件,并按年和站点计算平均气温以及生 ...
nc文件中变量名和数据集时间单位如何查看啊 聆風祈 发表于 2023-4-17 18:54
nc文件中变量名和数据集时间单位如何查看啊
您可以使用MATLAB中的ncdisp函数查看NetCDF文件中的变量名和数据集时间单位。下面是如何使用ncdisp函数的示例。
% 加载nc文件
filename = 'temperature_data.nc';
% 显示nc文件信息
ncdisp(filename);
在运行此代码后,MATLAB命令窗口将显示文件中的变量和属性。找到对应的气温变量(例如,temperature或air_temperature),并检查时间变量(通常为time)的单位。
时间单位可能类似于days since 1900-01-01,表示从1900年1月1日开始的天数。您还可能会看到诸如hours since 1900-01-01(从1900年1月1日开始的小时数)这样的时间单位。
根据您的数据集,您可能需要相应地调整上述计算平均气温的MATLAB代码示例中的时间计算。
本帖最后由 聆風祈 于 2023-4-17 19:19 编辑
isdkz 发表于 2023-4-17 18:56
您可以使用MATLAB中的ncdisp函数查看NetCDF文件中的变量名和数据集时间单位。下面是如何使用ncdisp函数的 ...
查看之后发现是网格数据
Variables:
lat
Size: 73x1
Dimensions: lat
Datatype: single
Attributes:
units = 'degrees_north'
actual_range=
long_name = 'Latitude'
standard_name = 'latitude'
axis = 'Y'
lon
Size: 144x1
Dimensions: lon
Datatype: single
Attributes:
units = 'degrees_east'
long_name = 'Longitude'
actual_range=
standard_name = 'longitude'
axis = 'X'
time
Size: 901x1
Dimensions: time
Datatype: double
Attributes:
long_name = 'Time'
delta_t = '0000-01-00 00:00:00'
avg_period = '0000-01-00 00:00:00'
prev_avg_period = '0000-00-01 00:00:00'
standard_name = 'time'
axis = 'T'
units = 'hours since 1800-01-01 00:00:0.0'
actual_range =
air
Size: 144x73x901
Dimensions: lon,lat,time
Datatype: single
Attributes:
long_name = 'Monthly Mean Air Temperature at sigma level 0.995'
valid_range = [-20002000]
units = 'degC'
add_offset = 0
scale_factor = 1
missing_value = -9.969209968386869e+36
precision = 1
least_significant_digit = 0
var_desc = 'Air Temperature'
statistic = 'Mean'
parent_stat = 'Individual Obs'
dataset = 'NCEP Reanalysis Derived Products'
level_desc = '0.995 sigma'
actual_range = [-73.78 42.146]
可以将其处理成一个工作簿一年,年平均气温按经纬度分布的excel文件么 聆風祈 发表于 2023-4-17 19:14
查看之后发现是网格数据
Variables:
lat
根据您提供的变量信息,下面是一个MATLAB代码示例,用于读取网格化气温数据的NetCDF文件,并按年计算平均气温,然后将结果保存到Excel文件中,其中每个工作表代表一年。
% 加载nc文件
filename = 'temperature_data.nc';
% 获取经度、纬度、时间和气温信息
lon = ncread(filename, 'lon');
lat = ncread(filename, 'lat');
time = ncread(filename, 'time');
air = ncread(filename, 'air');
% 计算每个时间单位的小时数
time_units = ncreadatt(filename, 'time', 'units');
time_hours = sscanf(time_units, 'hours since %*s') / 24;
% 计算逐年平均气温
years = unique(floor(time / (365 * time_hours)));
num_years = length(years);
annual_avg_temp = zeros(length(lat), length(lon), num_years);
for i = 1:num_years
year = years(i);
start_time = year * 365 * time_hours + 1;
end_time = start_time + 364 * time_hours;
annual_avg_temp(:, :, i) = mean(air(:, :, start_time:end_time), 3);
end
% 输出结果到Excel文件
excel_filename = 'Annual_Avg_Temperature.xlsx';
for i = 1:num_years
year = years(i);
sheet_name = sprintf('Year %d', year);
T = array2table(annual_avg_temp(:, :, i), 'VariableNames', cellstr(num2str(lon')), 'RowNames', cellstr(num2str(lat)));
writetable(T, excel_filename, 'Sheet', sheet_name, 'WriteRowNames', true);
end
disp('已将年平均气温按经纬度分布保存到Excel文件。');
请将filename变量更改为您的NetCDF文件名。此代码示例会将结果保存到名为Annual_Avg_Temperature.xlsx的Excel文件中。每个工作表代表一年,行名表示纬度,列名表示经度,单元格中的值表示该年该位置的平均气温。
注意:在运行此代码之前,请确保已安装了支持Excel文件读写的MATLAB插件。如果尚未安装,请在MATLAB命令窗口中输入以下命令:
addpath(fullfile(matlabroot, 'toolbox', 'matlab', 'xlswrite'));
如果您需要进一步的帮助,请随时提问。
isdkz 发表于 2023-4-17 19:34
根据您提供的变量信息,下面是一个MATLAB代码示例,用于读取网格化气温数据的NetCDF文件,并按年计算平均 ...
错误使用/
矩阵维度必须一致。
出错 untitled (第 15 行)
years = unique(floor(time / (365 * time_hours)));
运行后提示这个 聆風祈 发表于 2023-4-17 19:59
错误使用/
矩阵维度必须一致。
对不起,我犯了一个错误。time_hours应该是一个标量值,而不是数组。我们只需要提取小时数。这里是修复后的代码:
% 计算每个时间单位的小时数
time_units = ncreadatt(filename, 'time', 'units');
hour_str = regexp(time_units, '\d+', 'match');
time_hours = str2double(hour_str{1}) / 24;
% 其他代码保持不变...
这将解决矩阵维度不一致的问题。请使用这个修复后的代码片段替换之前的time_hours计算部分。如果您还有其他问题,请随时提问。 isdkz 发表于 2023-4-17 20:02
对不起,我犯了一个错误。time_hours应该是一个标量值,而不是数组。我们只需要提取小时数。这里是修复后 ...
修改之后提示这个
位置 3 处的索引超出数组边界。索引不能超过 901。
出错 untitled (第 254行)
annual_avg_temp(:, :, i) = mean(air(:, :, start_time:end_time), 3); 聆風祈 发表于 2023-4-17 20:10
修改之后提示这个
位置 3 处的索引超出数组边界。索引不能超过 901。
这个错误是因为在计算start_time和end_time时,没有将time数组中的起始时间考虑进去。以下是修复后的代码:
% 计算逐年平均气温
start_year = str2double(regexp(time_units, '\d{4}', 'match'));
years = start_year + unique(floor((time - time(1)) / (365 * time_hours)));
num_years = length(years);
annual_avg_temp = zeros(length(lat), length(lon), num_years);
for i = 1:num_years
year = years(i);
start_time = (year - start_year) * 365 * time_hours + 1;
end_time = start_time + 364 * time_hours;
if end_time > length(time) % 防止超出时间范围
end_time = length(time);
end
annual_avg_temp(:, :, i) = mean(air(:, :, start_time:end_time), 3);
end
% 其他代码保持不变...
这将解决数组索引越界的问题。请使用这个修复后的代码片段替换之前的逐年平均气温计算部分。如果您还有其他问题,请随时提问。 isdkz 发表于 2023-4-17 20:12
这个错误是因为在计算start_time和end_time时,没有将time数组中的起始时间考虑进去。以下是修复后的代码 ...
修改之后提示这样
无法执行赋值,因为左侧的大小为 73×144,右侧的大小为 144×73。
出错 untitled (第 28 行)
annual_avg_temp(:, :, i) = mean(air(:, :, start_time:end_time), 3); 聆風祈 发表于 2023-4-17 20:28
修改之后提示这样
无法执行赋值,因为左侧的大小为 73×144,右侧的大小为 144×73。
这个问题是由于在为annual_avg_temp数组分配值时,维度不匹配所致。我们需要将air数组的第一个和第二个维度转置。以下是修复后的代码:
% 计算逐年平均气温
start_year = str2double(regexp(time_units, '\d{4}', 'match'));
years = start_year + unique(floor((time - time(1)) / (365 * time_hours)));
num_years = length(years);
annual_avg_temp = zeros(length(lat), length(lon), num_years);
for i = 1:num_years
year = years(i);
start_time = (year - start_year) * 365 * time_hours + 1;
end_time = start_time + 364 * time_hours;
if end_time > length(time) % 防止超出时间范围
end_time = length(time);
end
annual_avg_temp(:, :, i) = mean(permute(air(:, :, start_time:end_time), ), 3);
end
% 其他代码保持不变...
这将解决维度不匹配的问题。请使用这个修复后的代码片段替换之前的逐年平均气温计算部分。如果您还有其他问题,请随时提问。 isdkz 发表于 2023-4-17 20:45
这个问题是由于在为annual_avg_temp数组分配值时,维度不匹配所致。我们需要将air数组的第一个和第二个维 ...
错误使用 array2table
'0 2.5 5 7.5 10 12.5 15
17.5 20 22.5 25 27.5 30 32.5
35 37.5 40 42.5 45 47.5 50
52.5 55 57.5 60 62.5 65 67.5
70 72.5 75 77.5 80 82.5 85
87.5 90 92.5 95 97.5 100 102.5
105 107.5 110 112.5 115 117.5 120
122.5 125 127.5 130 132.5 135 137.5
140 142.5 145 147.5 150 152.5 155
157.5 160 162.5 165 167.5 170 172.5
175 177.5 180 182.5 185 187.5 190
192.5 195 197.5 200 202.5 205 207.5
210 212.5 215 217.5 220 222.5 225
227.5 230 232.5 235 237.5 240 242.5
245 247.5 250 252.5 255 257.5 260
262.5 265 267.5 270 272.5 275 277.5
280 282.5 285 287.5 290 292.5 295
297.5 300 302.5 305 307.5 310 312.5
315 317.5 320 322.5 325 327.5 330
332.5 335 337.5 340 342.5 345 347.5
350 352.5 355 357.5' 超过了表变量名称允许的最大长度。
出错 untitled (第 37 行)
T = array2table(annual_avg_temp(:, :, i), 'VariableNames', cellstr(num2str(lon')), 'RowNames', cellstr(num2str(lat)));
修改之后这样 isdkz 发表于 2023-4-17 20:45
这个问题是由于在为annual_avg_temp数组分配值时,维度不匹配所致。我们需要将air数组的第一个和第二个维 ...
大佬在嘛{:10_254:} isdkz 发表于 2023-4-17 20:45
这个问题是由于在为annual_avg_temp数组分配值时,维度不匹配所致。我们需要将air数组的第一个和第二个维 ...
大佬,修改完之后这里跑不通
错误使用 array2table
'0 2.5 5 7.5 10 12.5 15
17.5 20 22.5 25 27.5 30 32.5
35 37.5 40 42.5 45 47.5 50
52.5 55 57.5 60 62.5 65 67.5
70 72.5 75 77.5 80 82.5 85
87.5 90 92.5 95 97.5 100 102.5
105 107.5 110 112.5 115 117.5 120
122.5 125 127.5 130 132.5 135 137.5
140 142.5 145 147.5 150 152.5 155
157.5 160 162.5 165 167.5 170 172.5
175 177.5 180 182.5 185 187.5 190
192.5 195 197.5 200 202.5 205 207.5
210 212.5 215 217.5 220 222.5 225
227.5 230 232.5 235 237.5 240 242.5
245 247.5 250 252.5 255 257.5 260
262.5 265 267.5 270 272.5 275 277.5
280 282.5 285 287.5 290 292.5 295
297.5 300 302.5 305 307.5 310 312.5
315 317.5 320 322.5 325 327.5 330
332.5 335 337.5 340 342.5 345 347.5
350 352.5 355 357.5' 超过了表变量名称允许的最大长度。
出错 untitled (第 37 行)
T = array2table(annual_avg_temp(:, :, i), 'VariableNames', cellstr(num2str(lon')), 'RowNames', cellstr(num2str(lat))); 聆風祈 发表于 2023-4-18 22:18
大佬,修改完之后这里跑不通
错误使用 array2table
'0 2.5 5 7.5 ...
问题是由于变量名和行名超出了Excel表格允许的最大长度。为解决这个问题,我们需要将经度和纬度的值转换为更短的字符串。以下是修复后的代码:
% 输出结果到Excel文件
excel_filename = 'Annual_Avg_Temperature.xlsx';
for i = 1:num_years
year = years(i);
sheet_name = sprintf('Year %d', year);
% 创建更短的经度和纬度字符串
lon_str = cellstr(sprintfc('Lon%.1f', lon));
lat_str = cellstr(sprintfc('Lat%.1f', lat));
T = array2table(annual_avg_temp(:, :, i), 'VariableNames', lon_str, 'RowNames', lat_str);
writetable(T, excel_filename, 'Sheet', sheet_name, 'WriteRowNames', true);
end
disp('已将年平均气温按经纬度分布保存到Excel文件。');
这将创建更短的经度和纬度字符串(例如,Lon0.0,Lat90.0),用作Excel表格的变量名和行名。
请使用这个修复后的代码片段替换之前的Excel输出部分。如果您还有其他问题,请随时提问。
页:
[1]
2