%% URL read for Real-time Weather Station Measurements
%
clear all
close all
clc
%
station_repos = 'http://w1.weather.gov/data/obhistory/'; % This is where
% the weather stations are located at www.weather.gov
% You type in your address and then look for the 4-letter station
% identifier (for example, if you type in '10024' for NYC, the station
% ID for that Zip Code is 'KNYC' - Central Park's weather station
%
station_name_formal = 'Austin-Bergstrom International Airport';
station_ID = 'KAUS';
%
% concatenate station repository with your local station
%
web_url = strcat(station_repos,station_ID,'.html');
%
% Crawl the URL for data
web_str_crawl = webread(web_url);
%
% Now for the fun - parsing the data!
%
station_table = data_reformat(web_str_crawl);
%
% Preparing the Figure to Plot
[fig1,ax1,dcm_obj] = fig_open();
%
% Now reformat the data and plot it!
%
plot_algo(station_table,station_name_formal,station_ID,[7,8])
%
fig1.Visible='on';
saveas(fig1,'test.png')
%
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%------------------------FUNCTIONS--------------------------------------%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
function station_table = data_reformat(web_url_str)
%
% Parse each row, which in html is identified by
| , then put each
% into the station_parse variable
station_parse = {};
for jj = 1:length(web_url_str)-4
if web_url_str(jj:jj+4)==''
for kk = 1:80
if web_url_str(jj-kk)=='>'
station_parse{end+1} = web_url_str(jj-kk+1:jj-1);
break
end
end
end
end
% shift data to get rid of the extra headers
station_vec = {};
n_shift = 9;
for ll = 1:length(station_parse)
if ll>=n_shift
station_vec{ll-n_shift+1} =station_parse{ll};
end
end
%
% reformat the data into an easily-readable table
%
col_size = 18;
station_table = {zeros(floor(length(station_vec)/col_size)+1,col_size)};
% I rewrote the headers to make them more friendly for labeling
station_header = {'Date','Time (Local)','Wind [MPH]','Visibility [Miles]','Weather Cond.',...
'Sky Cond.','Air Temperature [F]','Dew Point [F]','Temp (6 Hour Max) [F]','Temp (6 Hour Min)','Relative Humidity [%]',...
'Wind Chill [F]','Heat Index [F]','Pressure (Alt, inches)','Pressure (Sea, mbar)',...
'Precipitation (1 hr) [inches]','Precipitation (inches) [3 hr]','Precipitation (inches) [6 hr]'};
% This is the loop where the table is created and formatted
for mm = 1:floor(length(station_vec)/col_size)+1
for nn = 1:col_size
if mm == 1
station_table{mm,nn} = station_header{nn};
else
pp = (mm-2)*col_size+nn;
if nn==11
station_table{mm,nn} = station_vec{pp}(1:2);
else
station_table{mm,nn} = station_vec{pp};
end
end
end
end
end
function [fig1,ax1,dcm_obj] = fig_open()
set(0,'defaultfigurecolor',[1 1 1]) % white background
set(0,'defaultaxesfontname','cambria math') % beautify the axes a bit
scrn_size = get(0,'ScreenSize'); % get size of screen
shrink_pct = 0.1; % shrink the figure by 10%
%
fig1 = figure('Visible','off','DefaultAxesFontSize',20,'Position',...
[scrn_size(1)+(scrn_size(3)*shrink_pct) scrn_size(2)+(scrn_size(4)*shrink_pct)...
scrn_size(3)-(scrn_size(3)*2*shrink_pct) scrn_size(4)-(scrn_size(4)*2*shrink_pct)]); % shrinking the figure
%
ax1 = gca;
dcm_obj = datacursormode(fig1); % enable control of datatips
% set(dcm_obj,'UpdateFcn',@myupdatefcn) % this will be used to configure
% data tips
set(ax1,'fontsize',22,'Color',[0.8 0.8 0.8],'gridcolor',[1 1 1],'gridalpha',0.9) % set the axis color
% to compliment the white background
%
xlabel('Time [Day HH:MM]') % x-axis date label
hold all
grid on % grid for more contrast in the axes
end
%
function [datenum_vec,var_pick,var_name] = parse_and_format(station_table,var_col)
curr_time = datetime(); % get the current time for year information
datenum_vec = []; var_pick = [];
var_name = station_table{1,var_col}; % variable name
for ss = 2:length(station_table) % starting at the second row since the first contains the variable names
var_pick = [var_pick,str2double(station_table{ss,var_col})];
if isempty(str2double(station_table{ss,var_col})) % if there is no data in the row, skip the loop
continue
end
if ss==2 % making sure the first row is the reference year, month, and day
datenum_vec = [datenum_vec,datenum(year(curr_time),month(curr_time),str2num(station_table{ss}),str2num(station_table{ss,2}(1:2)),str2num(station_table{ss,2}(4:5)),0)];
else
if str2double(station_table{ss})>str2double(station_table{2}) % this ensures that if the date grows, then the day is in the previous month
if month(curr_time)==1 % if it's december, then we have to roll back the month and year
datenum_vec = [datenum_vec,datenum(year(curr_time)-1,12,str2double(station_table{ss}),str2double(station_table{ss,2}(1:2)),str2double(station_table{ss,2}(4:5)),0)];
else % end of month, roll back month
datenum_vec = [datenum_vec,datenum(year(curr_time),month(curr_time)-1,str2double(station_table{ss}),str2double(station_table{ss,2}(1:2)),str2double(station_table{ss,2}(4:5)),0)];
end
else
datenum_vec = [datenum_vec,datenum(year(curr_time),month(curr_time),str2double(station_table{ss}),str2double(station_table{ss,2}(1:2)),str2double(station_table{ss,2}(4:5)),0)];
end
end
end
end
function plot_algo(station_table,station_name_formal,home_station,var_select)
legend_str = {};
for ii = 1:length(var_select) % loop through variables to ensure legend catches each
[datenum_vec,var_pick,var_name] = parse_and_format(station_table,var_select(ii)); % send variable through parse function
% plotting traits
sz = 10; % size of marker
color_map = lines; % colormap used for lines and markers
if length(var_select)<=2 % this is particular to my dataset (METAR)
switch ii
case 1 % if only 1 variable, make 1 y-axis label
ylabel(var_name)
case 2 % if two variables, make two y-axis labels
yyaxis right; % second y-axis to the right
y2 = gca;
ylabel(var_name)
y2.YColor = color_map(ii,:); % ensure the color of the axis matches the second line
end % in my case, I'm chosing to discard the y-labels if more than 2 variables are entered
end
% plot specifics: -s creates a square marker with a line
plot(datenum_vec,var_pick,'-s','linewidth',3,'color',color_map(ii,:),...
'MarkerFaceColor',(1-color_map(ii,:))/1.5+color_map(ii,:),'MarkerEdgeColor',[25 25 25]./256,...
'MarkerSize',sz)
% title handling for month and year
curr_time = datetime();
title(strcat('Weather for {}',station_name_formal,'{ }(',home_station,') in {}',datestr(curr_time,'mmmm, yyyy')))
xlabel('Time [Day HH:MM]')
% chosing to step through x-values by 6 (72/6 = 12 x-ticks)
xticks(datenum_vec(end:-6:1))
datetick(gca,'x','dd HH:MM','keepticks')
% rotating the x-ticks so they don't overlap
xtickangle(20)
% setting the limits
xlim([datenum_vec(end) datenum_vec(1)])
% appending the names to the legend handler
legend_str{end+1} = var_name;
end
% white background and letting MATLAB choose the best location for the
% legend
legend(legend_str,'Location','Best','Color','white')
end