The data of the selected time period is categorized by peak wave direction and
significant wave height.
The length of a petal (or a portion of the petal), corresponds to the
frequency of occurrence.
The peak wave direction categories (degrees clockwise from True North):
- 11.25 - 33.75 (centered at 22.5)
- 33.75 - 56.25 (centered at 45.0)
- 56.25 - 78.75 (centered at 67.5)
- ...
- 349.0 - 11.5 (centered at 0.0)
The color coded significant wave height categories (meters):
Source Code:
%-----------------------------------------------------------------------
% Name:
% .dbase/web_programs/plotpro/matlab_scripts/wave_rose.m
% Description:
% Creates a wind_rose plot by calling rose.m
% Called by:
% .f90/plot_utils.make_plot
%-----------------------------------------------------------------------
path(path,'/project/dbase/web_programs/plotpro/matlab_scripts');
%pid = '02474';
cdip_rose(pid,'wave');
quit;
Source Code:
%-------------------------------------------------------------------------------
% Name:
% .dbase/web_programs/plotpro/matlab_scripts/cdip_rose.m
% Description:
% Creates a rose plot using parameter file data, for either
% wind speed and wind direction, wave hs and wave direction, or
% peak period and wave direciton.
% Calls rose_polar.m to plot lines on polar plot.
% Called by:
% rose_wind.m or rose_wave.m
%-------------------------------------------------------------------------------
function cdip_rose(pid, type)
% ADD PATH TO ACCESS MATLAB SCRIPTS
path(path,'/project/dbase/web_programs/plotpro/matlab_scripts');
wkg = wkg_path;
% SET-UP FIGURE
figure('position',[10 10 700 800],'visible', 'off');
% LOAD THE DATA
eval(['load ',wkg,'list.',pid,'01']);
% GET STATION INFO
info = read_info_file([pid,'01'],wkg);
% SET PARAMETERS FOR ROSE TYPE
if ( type == 'wind' )
idx = [12,13];
amplitude_label = 'WIND SPEED (m/s)';
graph_title = 'WIND ROSE';
radial_edge = 1:1:20; % bins for speed
line_len = 0.06;
width_delta = 5;
elseif ( type == 'wave' )
idx = [6,8];
amplitude_label = 'SIG WAVE HEIGHT (m)';
graph_title = 'WAVE ROSE';
if ( max(list(:,idx(1))) > 4 )
radial_edge = 1:1:15; % bins for wave height
line_len = 0.06;
width_delta = 5;
else
line_len = 0.09;
width_delta = 3;
radial_edge = .5:.5:4; % bins for wave height
end
else
idx = [7,8];
amplitude_label = 'PEAK PERIOD (s)';
graph_title = 'PERIOD ROSE';
radial_edge = 2:2:30; % bins for peak period
line_len = 0.09;
width_delta = 2;
end
val = list(:,idx(1));
dir = list(:,idx(2));
k = find( dir >=0 & val >=0 );
if ( isempty(k) )
'ERROR: no direction or value data'
quit;
end
val = val(k);
dir = dir(k);
num_observations = length(val);
last_observation = k(length(k));
first_observation = k(1);
deg_interval = 22.5;
centers = deg_interval:deg_interval:360;
num_bins = length(centers);
% Note: this defines an extra bin
upper_edge = [deg_interval/2:deg_interval:360,360];
% TAG DIRECTION INTO BINS
[dir_sorted,I] = sort(dir);
dir_tag(1:num_observations) = -1;
k = 1;
for i=1:length(upper_edge)
for j=k:num_observations
if ( dir_sorted(j) <= upper_edge(i) & dir_tag(I(j)) < 0 )
dir_tag(I(j)) = i;
else
k = j;
break;
end
end
end
% TAG SPEED/HS INTO BINS
[val_sorted,I] = sort(val);
val_tag(1:num_observations) = -1;
k = 1;
for i=1:length(radial_edge)
for j=k:num_observations
if ( val_sorted(j) <= radial_edge(i) & val_tag(I(j)) < 0 )
val_tag(I(j)) = i;
else
k = j;
break;
end
end
end
% tag those > our max hs.
for i=1:num_observations
if ( val_tag(I(i)) < 0 )
val_tag(I(i)) = length(radial_edge) + 1;
end
end
% MAKE A COUNT OF EACH COMBINATION, DIRECTION AND SPEED/HS
bins = zeros(length(upper_edge),length(radial_edge)+1);
for i=1:num_observations
bins(dir_tag(i),val_tag(i)) = bins(dir_tag(i),val_tag(i)) + 1;
end
% COMBINE FIRST ROW INTO LAST ROW
bins(length(upper_edge),:) = bins(length(upper_edge),:) + bins(1,:);
% CREATE RELATIVE FREQUENCIES
% bins =
% row - direction: 1=22.5, 2=45, ... last=360.(direction)
% col - speed: 1=0-2, 2=2-4, ... last=18-20. (linewidth)
% val - frequency: (linelength)
bin_sum = sum(sum(bins));
bins = bins/bin_sum;
max_rho = max(sum(bins'))
start_rho = .20 * max_rho;
% CREATE INPUTS AND RUN ROSE_POLAR FOR EACH SPEED OR HEIGHT
linewidths = 2:width_delta:2+(length(radial_edge))*width_delta
colors = colormap(jet(length(radial_edge)+1));
colors(4,1) = .5;
colors(4,3) = .9;
centers_rad = (centers / 360) * 2 * pi;
max_col = 0;
for (col=1:length(radial_edge)+1)
rho = [];
theta = [];
if ( any(bins(:,col)) )
max_col = max(col,max_col);
for ( row=2:length(upper_edge) )
if ( bins(row,col) > 0 )
if ( col > 1 )
prev = start_rho + sum(bins(row,1:(col-1)));
else
prev = start_rho;
end
rho = [ rho prev prev+bins(row,col) NaN ];
theta = [ theta centers_rad(row-1) centers_rad(row-1) NaN ];
end
end
sz = size(theta);
theta = theta(1,1:sz(2)-1);
rho = rho(1,1:sz(2)-1);
ph = rose_polar(theta, rho, '-', num_bins, max_rho+start_rho);
hold on;
set(ph,'linewidth',linewidths(col));
set(ph,'color',colors(col,:));
end
end
% RE-ORIENT AXIS SO 0=NORTH, 90=EAST (i.e. increasing clockwise)
set(gca,'cameraposition',[ 0.01 0 -100]);
% RE-ORIENT WHEEL ON FIGURE WINDOW
set(gcf,'paperposition',[.25 .5 8 10]);
% default settings: set(gca,'position',[.13 .16 .775 .815]);
set(gca,'position',[.14 .13 .70 .736129]);
% WRITE TEXT ON FIGURE, FIRST SET AXES FOR ENTIRE FIGURE REGION
ah_text = axes('position',[0 0 1 1], 'units', 'normal', 'visible', 'off');
th=text(.5,.86,graph_title, 'fontsize',30,'color',[1, .3 .3],...
'horizontalalignment','center','fontweight','bold');
text(.5,.95,[info.stnid,' ',info.stname], 'fontsize',20,'color','blue',...
'horizontalalignment','center');
% .94, .92, .90 -> .88 .86 .84
% CREATE START-END DATE STRING
start_string = datestr(list(first_observation,1:6));
end_string = datestr(list(last_observation,1:6));
start_string(3) = '/'; start_string(7) = '/';
end_string(3) = '/'; end_string(7) = '/';
date_string = [start_string,' - ', end_string,' UTC'];
text(.5,.925,date_string, 'fontsize',14,'color','blue',...
'horizontalalignment','center');
% PUT NUMBER OF OBSERVATIONS
text(.5,.905,['Total Number of Occurrences = ',num2str(num_observations)], ...
'fontsize',14,'color','blue','horizontalalignment','center');
% MAKE BLUE BOX OUTLINE AROUND PLOT
blue_box(0.01);
% PUT A LEGEND ON THE PLOT
ah_wheel = gca; % save wheel axis for later
ax_pos = [ .03 .10 .8 .1 ];
leg_ah = axes('position',ax_pos,'visible','off','box','on');
left_start = .05;
line_height = 0;
text_y = 0;
start_line = left_start;
line_y = [ line_height line_height ];
for col=1:max_col
if ( col == length(radial_edge)+1 )
leg_entry = ['>',num2str(radial_edge(col-1))];
elseif ( col == 1 )
leg_entry = ['0-', num2str(radial_edge(col))];
else
leg_entry = [num2str(radial_edge(col-1)),'-',num2str(radial_edge(col))];
end
line_x = [start_line start_line + line_len];
start_line = start_line + line_len;
text_x = mean(line_x);
text_y = linewidths(col)/65 + .15;
th = text(text_x,text_y,leg_entry,'horizontalalignment','center');
ph = line(line_x,line_y);
set(ph,'linewidth',linewidths(col));
set(ph,'color',colors(col,:));
end
%text(line_x(2)/2,text_y+0.5,amplitude_label,'fontsize',12,...
text(left_start,text_y+0.5,amplitude_label,'fontsize',12,...
'horizontalalignment','left');
set(gca,'xlim',[0 1.15]);
set(gca,'ylim',[-1 1]);
ax_pos(2) = .12 - linewidths(max_col)/650;
set(gca,'position',ax_pos);
% PRINT TO PNG
set(gcf, 'visible','off');
png_name = [wkg,'plot_',pid,'.png'];
print(gcf,'-dpng','-r300',png_name);
Source Code:
function hpol = rose_polar(theta,rho,line_style,num_spokes,maxrho)
%
%
% ROSE_POLAR Specialized polar plot for wave/wind roses.
%
% Modified from matlab's polar.m by GAC (look for GAC tags below).
%
% ROSE_POLAR(THETA, RHO, LINE_STYLE, NUM_SPOKES) makes a plot
% using polar coordinates of the angle THETA, in radians, versus
% the radius RHO using string LINE_STYLE with NUM_SPOKES angular
% divisions.
%
% Called by cdip_rose.m
if nargin < 1
error('Requires 2 or 3 input arguments.')
elseif nargin == 2
if isstr(rho)
line_style = rho;
rho = theta;
[mr,nr] = size(rho);
if mr == 1
theta = 1:nr;
else
th = (1:mr)';
theta = th(:,ones(1,nr));
end
else
line_style = 'auto';
end
% GAC - debug
line_style
elseif nargin == 1
line_style = 'auto';
rho = theta;
[mr,nr] = size(rho);
if mr == 1
theta = 1:nr;
else
th = (1:mr)';
theta = th(:,ones(1,nr));
end
end
if isstr(theta) | isstr(rho)
error('Input arguments must be numeric.');
end
if ~isequal(size(theta),size(rho))
error('THETA and RHO must be the same size.');
end
% get hold state
cax = newplot;
next = lower(get(cax,'NextPlot'));
hold_state = ishold;
% get x-axis text color so grid is in same color
tc = get(cax,'xcolor');
ls = get(cax,'gridlinestyle');
% Hold on to current Text defaults, reset them to the
% Axes' font attributes so tick marks use them.
fAngle = get(cax, 'DefaultTextFontAngle');
fName = get(cax, 'DefaultTextFontName');
fSize = get(cax, 'DefaultTextFontSize');
fWeight = get(cax, 'DefaultTextFontWeight');
fUnits = get(cax, 'DefaultTextUnits');
set(cax, 'DefaultTextFontAngle', get(cax, 'FontAngle'), ...
'DefaultTextFontName', get(cax, 'FontName'), ...
'DefaultTextFontSize', get(cax, 'FontSize'), ...
'DefaultTextFontWeight', get(cax, 'FontWeight'), ...
'DefaultTextUnits','data')
% only do grids if hold is off
if ~hold_state
% make a radial grid
hold on;
% maxrho = max(abs(rho(:)));
hhh=plot([-maxrho -maxrho maxrho maxrho],[-maxrho maxrho maxrho -maxrho]);
set(gca,'dataaspectratio',[1 1 1],'plotboxaspectratiomode','auto')
v = [get(cax,'xlim') get(cax,'ylim')];
ticks = sum(get(cax,'ytick')>=0);
delete(hhh);
% check radial limits and ticks
% GAC - modified
minrho = min(abs(rho(:)));
rmin = minrho; rmax = v(4);
% GAC - modified
% rticks = max(ticks-1,2);
rticks = ticks;
if rticks > 7 % see if we can reduce the number
if rem(rticks,2) == 0
rticks = rticks/2;
elseif rem(rticks,3) == 0
rticks = rticks/3;
end
end
% define a circle
th = 0:pi/50:2*pi;
xunit = cos(th);
yunit = sin(th);
% now really force points on x/y axes to lie on them exactly
inds = 1:(length(th)-1)/4:length(th);
xunit(inds(2:2:4)) = zeros(2,1);
yunit(inds(1:2:5)) = zeros(3,1);
% plot background if necessary
if ~isstr(get(cax,'color')),
patch('xdata',xunit*rmax,'ydata',yunit*rmax, ...
'edgecolor',tc,'facecolor',get(gca,'color'),...
'handlevisibility','off');
end
% GAC - DRAW RADIAL CIRCLES
c82 = cos(82*pi/180);
s82 = sin(82*pi/180);
rinc = (rmax-rmin)/rticks;
for i= rmin:rinc:rmax
hhh = plot(xunit*i,yunit*i,ls,'color',tc,'linewidth',1,...
'handlevisibility','off');
if ( i == rmin )
set(hhh,'linestyle','-','linewidth',1)
else
frq = round((i-rmin)*100);
frq = frq/100;
text((i-rmin+rinc)*c82,(i-rmin+rinc)*s82, ...
num2str(frq),'verticalalignment','bottom',...
'horizontalalignment','center','color',[0 0 1],...
'handlevisibility','off')
end
end
text((1.2*rmax)*c82,(1.2*rmax)*s82, {'frequency';' of';'occurrence'}, ...
'horizontalalignment','left','color',...
[0 0 1],'verticalalignment','bottom', ...
'handlevisibility','off')
% GAC - MAKE OUTSIDE CIRCLE SOLID
set(hhh,'linestyle','-','linewidth',1);
% GAC - PLOT SPOKES AND ANNOTATE WITH DEGREE MARKERS
rt = 1.1*rmax;
rtt = 1.3*rmax;
for ( th = (1/num_spokes : 1/num_spokes: 1)*2*pi )
cst = cos(th); snt = sin(th);
x = [ rmin*cst (rmax)*cst ];
y = [ rmin*snt (rmax)*snt ];
plot(x,y,ls,'color',tc,'linewidth',1,...
'handlevisibility','off')
spoke_degree = round(th * (180 / pi) * 10)/10;
if ( spoke_degree == 360 ) spoke_degree = 0; end
text(rt*cst,rt*snt,num2str(spoke_degree),...
'horizontalalignment','center',...
'handlevisibility','off');
end
% GAC - PUT 'N', 'S', 'E', 'W' ON PLOT
text(rtt*cos(0),rtt*sin(0),'N', ...
'horizontalalignment','center',...
'fontsize',16,...
'color','r',...
'handlevisibility','off');
text(rtt*cos(pi/2),rtt*sin(pi/2),'E', ...
'horizontalalignment','center',...
'fontsize',16,...
'color','r',...
'handlevisibility','off');
text(rtt*cos(pi),rtt*sin(pi),'S', ...
'horizontalalignment','center',...
'fontsize',16,...
'color','r',...
'handlevisibility','off');
text(rtt*cos(-pi/2),rtt*sin(-pi/2),'W', ...
'horizontalalignment','center',...
'fontsize',16,...
'color','r',...
'handlevisibility','off');
% set view to 2-D
view(2);
% set axis limits
axis(rmax*[-1 1 -1.15 1.15]);
end % if hold_state
% Reset defaults.
set(cax, 'DefaultTextFontAngle', fAngle , ...
'DefaultTextFontName', fName , ...
'DefaultTextFontSize', fSize, ...
'DefaultTextFontWeight', fWeight, ...
'DefaultTextUnits',fUnits );
% transform data to Cartesian coordinates.
xx = rho.*cos(theta);
yy = rho.*sin(theta);
% GAC - jul 24, 2009
% plot data on top of grid
%if strcmp(line_style,'auto')
% q = plot(xx,yy);
%else
q = plot(xx,yy,line_style);
%end
if nargout > 0
hpol = q;
end
if ~hold_state
set(gca,'dataaspectratio',[1 1 1]), axis off; set(cax,'NextPlot',next);
end
set(get(gca,'xlabel'),'visible','on')
set(get(gca,'ylabel'),'visible','on')