如何在Matlab中实现震级与数据点大小匹配的地震数据绘图?
USGS地震数据可视化优化方案
以下是针对你需求的具体解决方案和优化代码:
一、震级到标记大小的合理转换
里氏震级是对数刻度,地震释放的能量与震级M满足 能量 ∝ 10^(1.5M),而geoscatter的标记大小参数单位是points²(面积),让标记面积和能量正相关,视觉上的大小差异才符合地震的实际能量差距。
替换你原来的临时转换方案,用以下逻辑更合理:
- 提取原始震级:
mag_raw = data(:,5); - 计算与能量正相关的面积值:
mag_size = 10.^(1.5 * mag_raw); - 缩放至视觉合理范围(比如5到200,避免小震级点看不见、大震级点过大):
mag_size = rescale(mag_size, 5, 200); - 处理震级为0的情况,用逻辑索引替代循环更高效:
mag_size(mag_size == 0) = 5;
这样转换贴合地震物理意义,视觉大小能准确反映能量差异。
二、限定视图到单个大陆/国家
直接用geolimits函数指定目标区域的经纬度范围即可,比如:
- 限定到中国区域:
geolimits([15, 55], [70, 135]); - 限定到北美大陆:
geolimits([10, 80], [-180, -50]);
调用该函数后,视图会自动聚焦到指定区域,你可以根据需求调整经纬度数值。
三、制作地震活动延时动画
要实现延时动画,需要先解析CSV中的时间数据,按时间排序后逐帧渲染:
- 解析时间列(USGS CSV第1列是
yyyy-mm-ddTHH:MM:SS格式的时间):time_str = readcell("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv", 'Range', 'A2:Aend'); time_datetime = datetime(time_str, 'InputFormat', 'yyyy-MM-dd''T''HH:mm:ss'); - 按时间排序所有数据:
[sorted_time, idx] = sort(time_datetime); sorted_lat = lat(idx); sorted_lon = lon(idx); sorted_mag_size = mag_size(idx); sorted_C = mag_raw(idx); - 按时间间隔(比如按天)分帧绘制,用
getframe捕捉帧后生成GIF:start_time = sorted_time(1); end_time = sorted_time(end); time_steps = start_time:days(1):end_time; fig = figure; geobasemap grayland; hold on; frames = []; for t = 1:length(time_steps)-1 mask = sorted_time >= time_steps(t) & sorted_time < time_steps(t+1); current_lat = sorted_lat(mask); current_lon = sorted_lon(mask); current_size = sorted_mag_size(mask); current_color = sorted_C(mask); geoscatter(current_lat, current_lon, current_size, current_color, 'filled'); geolimits([15, 55], [70, 135]); % 替换为目标区域 title(['地震活动:', datestr(time_steps(t), 'yyyy-mm-dd')]); frames(t) = getframe(fig); cla; % 清空当前帧,准备下一帧 end exportgif(fig, 'earthquake_animation.gif', frames, 'LoopCount', Inf, 'DelayTime', 0.5);
优化后的完整代码
clc; clear all; close all; % 读取地震数据(readmatrix自动跳过表头,列索引对应正确) data = readmatrix("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv"); lat = data(:,2); lon = data(:,3); mag_raw = data(:,5); % 震级到标记大小的合理转换 mag_size = 10.^(1.5 * mag_raw); mag_size = rescale(mag_size, 5, 200); % 缩放至视觉舒适范围 mag_size(mag_size == 0) = 5; % 处理0震级点,避免无显示 % 用震级作为颜色依据,比原cosd更有意义 C = mag_raw; % 绘制基础地震分布图 figure; A = geoscatter(lat, lon, mag_size, C, 'filled'); geobasemap grayland; % 限定视图到中国区域(可替换为其他目标区域) geolimits([15, 55], [70, 135]); title('过去一个月地震分布'); colorbar; ylabel('震级'); % ===== 可选:生成地震活动延时动画 ===== % 读取并解析时间列 time_str = readcell("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv", 'Range', 'A2:Aend'); time_datetime = datetime(time_str, 'InputFormat', 'yyyy-MM-dd''T''HH:mm:ss'); % 按时间排序所有数据 [sorted_time, idx] = sort(time_datetime); sorted_lat = lat(idx); sorted_lon = lon(idx); sorted_mag_size = mag_size(idx); sorted_C = mag_raw(idx); % 按天生成时间步 start_time = sorted_time(1); end_time = sorted_time(end); time_steps = start_time:days(1):end_time; fig_anim = figure; geobasemap grayland; hold on; frames = []; for t = 1:length(time_steps)-1 % 筛选当前时间区间内的地震 mask = sorted_time >= time_steps(t) & sorted_time < time_steps(t+1); current_lat = sorted_lat(mask); current_lon = sorted_lon(mask); current_size = sorted_mag_size(mask); current_color = sorted_C(mask); % 绘制当前帧 geoscatter(current_lat, current_lon, current_size, current_color, 'filled'); geolimits([15, 55], [70, 135]); title(['地震活动:', datestr(time_steps(t), 'yyyy-mm-dd')]); colorbar; ylabel('震级'); frames(t) = getframe(fig_anim); cla; % 清空画布,准备下一帧 end % 导出GIF动画 exportgif(fig_anim, 'earthquake_animation.gif', frames, 'LoopCount', Inf, 'DelayTime', 0.5);
内容的提问来源于stack exchange,提问作者MJM526
相关产品推荐
相关产品推荐

