NOAA GOES-19 imagery showing a dust storm affecting the entire Winnipeg area on the afternoon of May 14, 2026.
Reference:
https://classic107.com/articles/rare-dust-storm-warning-issued-across-southern-manitoba
% Created by LI Xu % Version 1.0 % August 6, 2026 % If you have any question about this code, % please do not hesitate to contact me via E-mail: % jeremy456@163.com % Blog: % http://blog.sciencenet.cn/u/lixujeremy % http://lixuworld.blogspot.com/ clear; clc; close all; timebegin=tic; cur_data=date; cur_time=fix(clock); str1=sprintf('%s %.2d:%.2d:%.2d', cur_data, cur_time(4), cur_time(5), cur_time(6)); fprintf('Time Begin: '); fprintf(str1); fprintf('\n'); % Define the Google Street Map tile URL % name = 'google_streets'; name='streets'; % url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/${z}/${y}/${x}'; % url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/${z}/${y}/${x}'; % url = 'https://mt1.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}&style=p.v:off|s.t:3|s.e:l|p.v:on'; % % url = 'https://mt1.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}&style=p.v:off|s.t:3|s.e:l|p.v:on'; % url = 'https://mt1.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}'; % url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/${z}/${y}/${x}'; % attribution = 'Map data ©2026 Google'; % url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/${z}/${x}/${y}.png'; % url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/dark_all/${z}/${x}/${y}.png'; % name = 'carto_voyager'; % attribution = '© OpenStreetMap contributors, © CARTO'; % url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/rastertiles/voyager/${z}/${x}/${y}.png'; % % % % Add it to your MATLAB basemap list % addCustomBasemap(name, url, 'Attribution', attribution); % url = 'https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/${z}/${y}/${x}'; % url = 'https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/NatGeo_World_Map/MapServer/tile/${z}/${y}/${x}'; % url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/rastertiles/voyager/${z}/${x}/${y}.png'; attribution = '© OpenStreetMap contributors, © CARTO'; url = 'https://mt1.google.com/vt/lyrs=s&x=${x}&y=${y}&z=${z}'; addCustomBasemap(name, url, 'Attribution', attribution); % addCustomBasemap(name, url, 'Attribution', 'Sources: Esri, National Geographic, Garmin'); % url = 'https://stamen-tiles.a.ssl.fastly.net/toner/${z}/${x}/${y}.png'; % addCustomBasemap('stamen_toner', url, 'Attribution', 'Map tiles by Stamen Design, CC BY 3.0'); % Create geographic axes with OpenStreetMap basemap figure; gx = geoaxes('Basemap', name); set(gcf, 'OuterPosition', get(0, 'ScreenSize')); f = gcf; % Define custom latitude/longitude range (Winnipeg-centered) % latRange = [49.76, 50.01]; % lonRange = [-97.45, -96.9]; latRange = [49.79+0.005+0.009, 49.82-0.0068]; lonRange = [-97.15+0.008, -97.13+0.004]; % Calculate aspect ratio for exact limits without expansion mean_lat = mean(latRange); cos_factor = cosd(mean_lat); ar = diff(latRange) / (diff(lonRange) * cos_factor); % Required height/width for axes % Set up resize function to maintain aspect and exact limits gx.Units = 'pixels'; f.Units = 'pixels'; f.SizeChangedFcn = @(~, ~) myresizefcn(gx, f, ar, latRange, lonRange); myresizefcn(gx, f, ar, latRange, lonRange); % Rotate the whole map figure visually view(gx, 2); % rotate3d(f, 'on'); % % rotate3d(gx, 'on'); % gx.View = [30 90]; gx.Grid = 'off'; gx.TickDir = 'none'; gx.LatitudeLabel.String = ''; gx.LongitudeLabel.String = ''; gx.FontSize = 0.01; % dat=cell2mat(dat); % lats=dat(:, 1); % lons=dat(:, 2); % nums=dat(:, 3); % hold on; % for i = 1:length(lats) % % Draw Circle % plot(gx, lats(i), lons(i), 'bo', 'MarkerSize', 18, 'MarkerFaceColor', 'y'); % % Draw Number % text(gx, lats(i), lons(i), num2str(nums(i)), ... % 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle', 'Color', 'blue', 'FontWeight','bold', 'FontSize', 15); % end % 49.81155561273022, -97.13142673818446 plot(gx, 49.81155561273022, -97.13142673818446, 'pentagram', 'MarkerSize', 20, 'MarkerFaceColor', 'blue'); hold off; gx.Grid = 'off'; gx.TickDir = 'none'; gx.LatitudeLabel.String = ''; gx.LongitudeLabel.String = ''; gx.FontSize = 0.01; % dim = [0.1 0.83 0.8 0.1]; % Position at the top center % str = 'Campus Water Fountain Map'; % % hAnn = annotation('textbox', dim, 'String', str, ... % 'EdgeColor', 'none', ... % No border % 'HorizontalAlignment', 'center', ... % 'VerticalAlignment', 'middle', ... % 'FontSize', 25, ... % 'FontWeight', 'bold', ... % 'Color', 'white', ... % 'Interpreter', 'none'); pause(3); otname='kunakmap_vector'; export_fig(otname, '-png', '-painters', '-r300'); close all; fprintf('Time Begin: '); fprintf(str1); fprintf('\n'); cur_data=date; cur_time=fix(clock); str2=sprintf('%s %.2d:%.2d:%.2d', cur_data, cur_time(4), cur_time(5), cur_time(6)); fprintf('Time End: '); disp(str2); timespan=toc(timebegin); fprintf('Time Span: %.4f s\n', timespan); disp('************************************************************'); function myresizefcn(gx, f, ar, latlim, lonlim) if (f.Position(4) / f.Position(3)) < ar % Figure is wide: constrain by height gx.Position(4) = f.Position(4) * 0.8; gx.Position(3) = gx.Position(4) / ar; % Center gx.Position(1) = (f.Position(3) - gx.Position(3)) / 2 + f.Position(1); gx.Position(2) = (f.Position(4) - gx.Position(4)) / 2 + f.Position(2); else % Figure is tall: constrain by width gx.Position(3) = f.Position(3) * 0.8; gx.Position(4) = gx.Position(3) * ar; % Center gx.Position(1) = (f.Position(3) - gx.Position(3)) / 2 + f.Position(1); gx.Position(2) = (f.Position(4) - gx.Position(4)) / 2 + f.Position(2); end % Re-apply limits to maintain exact range geolimits(gx, latlim, lonlim); end
% Created by LI Xu % Version 1.0 % August 28, 2025 % If you have any question about this code, % please do not hesitate to contact me via E-mail: % jeremy456@163.com % Blog: % http://blog.sciencenet.cn/u/lixujeremy % http://lixuworld.blogspot.com/ clear; clc; close all; timebegin=tic; cur_data=date; cur_time=fix(clock); str1=sprintf('%s %.2d:%.2d:%.2d', cur_data, cur_time(4), cur_time(5), cur_time(6)); fprintf('Time Begin: '); fprintf(str1); fprintf('\n'); import mlreportgen.ppt.* % 1. Create a presentation ppt = Presentation('AQ.pptx'); % 2. Create a slide (e.g., 'Blank' or 'Title and Content') slide = add(ppt, 'Title and Content'); replace(slide, 'Title', 'Measured Data Table'); % 3. Prepare your data (Cell array: Rows x Cols) data = {'Variable', 'Campus', 'Winnipeg'; 'Temperature (℃) ', '40', '15'; ... 'Relative Humidity (%)', '65', '70'; ... 'Wind speed (m/s)', '65', '70'; ... 'PM2.5 (μg/m³)', '65', '70'; ... 'PM10 (μg/m³)', '65', '70'; ... 'NO₂ (ppb)', '65', '70'; ... 'O₃ (ppb)', '65', '70'; ... 'CO₂ (ppm)', '65', '70'}; % 4. Create and add the table % 'Table' automatically creates rows/columns based on the data tableObj = Table(data); firstRow = tableObj.Children(1); firstRow.Style = {BackgroundColor('#296080'), FontColor('white'), Bold()}; tableObj.Style = {HAlign('center'), VAlign('middle'), Border('solid'), RowHeight('0.3in')}; % tableObj.ColWidths = {'1.5in', '1.0in', '1.0in'}; % Column 3: 1.0 inches (Winnipeg) spec1 = ColSpec('2.5 in'); spec2 = ColSpec('1.5 in'); spec3 = ColSpec('1.5 in'); % 2. Assign the array of specs to the table tableObj.ColSpecs = [spec1, spec2, spec3]; % 1. Target the specific cell (Row 2, Column 2) using entry(row, col) targetCell = entry(tableObj, 2, 2); % 2. Apply the background color targetCell.Style = {BackgroundColor('red')}; % 1. Target the specific cell (e.g., Row 2, Column 2) targetCell = entry(tableObj, 2, 2); % 2. Apply the font color (e.g., red) % You can use names like 'red', 'white', or hex codes like '#FF0000' targetCell.Style = [targetCell.Style, {FontColor('white')}]; % Add the table to the content placeholder replace(slide, 'Content', tableObj); % 5. Close and View close(ppt); rptview(ppt); fprintf('Time Begin: '); fprintf(str1); fprintf('\n'); cur_data=date; cur_time=fix(clock); str2=sprintf('%s %.2d:%.2d:%.2d', cur_data, cur_time(4), cur_time(5), cur_time(6)); fprintf('Time End: '); disp(str2); timespan=toc(timebegin); fprintf('Time Span: %.4f s\n', timespan); disp('*************************************************************************');
% ──────────────────────────────────────────────── % Compress large GIF → smaller GIF (same size, fewer colors) % ──────────────────────────────────────────────── inputGif = 'original.gif'; % ← change this outputGif = 'compressed_version.gif'; [frames, map] = imread(inputGif, 'Frames', 'all'); if size(frames,3) == 3 isRGB = true; else isRGB = false; end nFrames = size(frames, 4); % ── Super aggressive settings ── nColors = 16; % try 12 or 8 if still too big useDither = false; % no dither = smaller delayFactor = 4.0; % 4× slower → big size win frameStep = 3; % keep only every 3rd frame (big reduction) newFrames = cell(1, floor(nFrames / frameStep)); globalMap = []; k = 1; for i = 1:frameStep:nFrames if isRGB thisFrame = frames(:,:,:,i); else thisIndexed = frames(:,:,:,i); thisFrame = ind2rgb(thisIndexed, map); end if k == 1 if useDither [indexed, globalMap] = rgb2ind(thisFrame, nColors); else [indexed, globalMap] = rgb2ind(thisFrame, nColors, 'nodither'); end else if useDither indexed = rgb2ind(thisFrame, globalMap); else indexed = rgb2ind(thisFrame, globalMap, 'nodither'); end end newFrames{k} = indexed; k = k + 1; end % Timing – slow it down a lot info = imfinfo(inputGif); origDelay = info(1).DelayTime / 100; newDelay = origDelay * delayFactor; if newDelay < 0.05, newDelay = 0.05; end % reasonable min % Write imwrite(newFrames{1}, globalMap, outputGif, 'gif', ... 'LoopCount', Inf, ... 'DelayTime', newDelay); for kk = 2:numel(newFrames) imwrite(newFrames{kk}, globalMap, outputGif, 'gif', ... 'WriteMode', 'append', ... 'DelayTime', newDelay); end % Report origSize = dir(inputGif).bytes / 1e6; newSize = dir(outputGif).bytes / 1e6; fprintf('MATLAB: %.0f MB → %.0f MB (%.0f%% smaller)\n', origSize, newSize, (origSize-newSize)/origSize*100); disp(['Saved: ' outputGif]);