Wind rose - collateral points, continuous circle at 50% and the percentages on a line (west to center)

10 views (last 30 days)
Hello, I would like to make a wind rose just like figure 1, but the way I'm doing it just comes out as shown in figure 2.
code is below along with a txt file (zip):
function varargout = wind_rose(D,F,varargin)
%WIND_ROSE Wind rose of direction and intensity
%
% Syntax:
% [HANDLES,DATA] = WIND_ROSE(D,I,VARARGIN)
%
% Inputs:
% D Directions
% I Intensities
% VARARGIN:
% -dtype, type of input directions D, standard or meteo,
% if meteo, the conversion dnew=mod(-90-D,360) is done;
% if not meteo, standard is used (default)
% -n, number of D subdivisons
% -di, intensities subdivisons, default is automatic
% -ci, percentage circles to draw, default is automatic
% -labtitle, main title
% -lablegend, legend title
% -cmap, colormap [jet]
% -colors, to use instead of colormap, for each di
% -quad, Quadrant to show percentages [1]
% -ri, empty internal radius, relative to size of higher
% percentage [1/30]
% -legtype, legend type: 1, continuous, 2, separated boxes [2]
% -bcolor, full rectangle border color ['none']
% -lcolor, line colors for axes and circles ['k']
% -percbg, percentage labels bg ['w']
% -ax, to place wind rose on pervious axes, the input for ax
% must be [theax x y width], where theax is the previous
% axes, x and y are the location and width is the wind
% rose width relative to theax width (default=1/5)
% -parent, by default a new axes is created unless parent is
% given, ex, parent may be a subplot
% -iflip, flip the intensities as they go outward radially, ie,
% highest values are placed nearest the origin [{0} 1]
% -inorm, normalize intensities, means all angles will have 100%
% -incout, if 0, data outside di limits will not be used [0 {1}]
%
% Output:
% HANDLES Handles of all lines, fills, texts
% DATA Wind rose occurences per direction and intensity
handles=[];
%----------------------------------------------------------------------
% % Code changed
load waves.txt %load wave file
D =waves(:,1); %load wave direction
F =waves(:,2); %load wave height
%----------------------------------------------------------------------
% varargin options:
dtype='meteo';
nAngles=16;
ri=1/30;
quad=1;
legType=2;
percBg='w';
titStr='';
legStr='';
cmap=jet;
colors=[];
Ag=[0.5 1.0 1.5 2.0 2.5 3.0]; % intensity subdivs. --> wave height
ci=[0 10 20 30 40 50]; % percentage circles
lineColors='k';
borderColor='none';
onAxes=false;
iflip=0;
inorm=0;
parent=0;
IncHiLow=1; % include values higher and lower that the limits of Ag.
vin=varargin;
for i=1:length(vin)
if isequal(vin{i},'dtype')
dtype=vin{i+1};
elseif isequal(vin{i},'n')
nAngles=vin{i+1};
elseif isequal(vin{i},'ri')
ri=vin{i+1};
elseif isequal(vin{i},'quad')
quad=vin{i+1};
elseif isequal(vin{i},'legtype')
legType=vin{i+1};
elseif isequal(vin{i},'percbg')
percBg=vin{i+1};
elseif isequal(vin{i},'labtitle')
titStr=vin{i+1};
elseif isequal(vin{i},'lablegend')
legStr=vin{i+1};
elseif isequal(vin{i},'cmap')
cmap=vin{i+1};
elseif isequal(vin{i},'colors')
colors=vin{i+1};
elseif isequal(vin{i},'di')
Ag=vin{i+1};
elseif isequal(vin{i},'ci')
ci=vin{i+1};
elseif isequal(vin{i},'lcolor')
lineColors=vin{i+1};
elseif isequal(vin{i},'bcolor')
borderColor=vin{i+1};
elseif isequal(vin{i},'ax')
ax=vin{i+1};
try
onAxes=ax(1);
onAxesX=ax(2);
onAxesY=ax(3);
onAxesR=ax(4);
catch
disp(':: cannot place wind rose on axes, bad argument for ax')
return
end
elseif isequal(vin{i},'iflip')
iflip=vin{i+1};
elseif isequal(vin{i},'inorm')
inorm=vin{i+1};
elseif isequal(vin{i},'parent')
parent=vin{i+1};
elseif isequal(vin{i},'incout')
IncHiLow=vin{i+1};
end
end
% other options:
% size of the full rectangle:
rs=1.2;
rl=1.7;
% directions conversion:
if isequal(dtype,'meteo')
D=mod(90-D,360);
end
% angles subdivisons:
D=mod(D,360);
Ay=linspace(0,360,nAngles+1)-0.5*360/nAngles;
% calc instensity subdivisions:
if isempty(Ag)
% gen Ag:
f=figure('visible','off');
plot(F); axis tight;
yl=get(gca,'ytick');
close(f)
dyl=diff(yl); dyl=dyl(1);
if min(F)<yl(1), yl=[yl(1)-dyl yl]; end
if max(F)>yl(end), yl=[yl yl(end)+dyl]; end
Ag=yl;
end
for i=1:length(Ay)-1
if i==1
I=find( (D>=Ay(i) & D<Ay(i+1)) | D>=Ay(end));
else
I=find(D>=Ay(i) & D<Ay(i+1));
end
b=F(I);
for j=1:length(Ag)-1
if j==length(Ag)-1
J=find(b>=Ag(j) & b<=Ag(j+1)); % include data with last Agg
else
J=find(b>=Ag(j) & b<Ag(j+1));
end
E(i,j)=length(J);
end
if IncHiLow
E(i,1)=length(find(b<Ag(2)));
E(i,end)=length(find(b>=Ag(end-1)));
end
end
b=sum(E,2)/length(D)*100;
% normalize data:
if inorm
n=sum(E,2);
for i=1:length(n)
E(i,:)=E(i,:)/n(i);
end
b=100*ones(size(b));
end
% check if has values higher or lower than the Ag limits
hasH=length(find(F>Ag(end)));
hasL=length(find(F<Ag(1)));
% calc number of percentage circles to draw:
if isempty(ci)
if inorm
ci=[25 50 75];
g=120;
ncircles=3;
else
dcircles=[1 2 5 10 15 20 25 30 50];
ncircles=3;
d=abs(1./(dcircles/max(b))-ncircles);
i=find(d==min(d));
d=dcircles(i(1));
if d*ncircles<max(b)
ncircles=ncircles+1;
end
ci=[1:ncircles]*d;
g=ncircles*d;
end
else
ncircles=length(ci);
g=max(max(ci),max(b));
end
% plot axes, percentage circles and percent. data:
if parent
wrAx=parent;
set(wrAx,'units','normalized');
else
wrAx=axes('units','normalized');
end
ri=g*ri;
handles(end+1)=fill([-rs*g rl*g rl*g -rs*g],[-rs*g -rs*g rs*g rs*g],'w',...
'EdgeColor',borderColor);
if onAxes
set(handles(end),'facecolor','none')
end
hold on
handles(end+1)=plot([-g-ri -ri nan ri g+ri nan 0 0 nan 0 0],...
[0 0 nan 0 0 nan -g-ri -ri nan ri g+ri],':','color',lineColors);
t0=[0:360]*pi/180;
labs=[];
Ang=[1/4 3/4 5/4 7/4]*pi;
Valign={'top' 'top' 'bottom' 'bottom'};
Halign={'right' 'left' 'left' 'right'};
for i=1:ncircles
x=(ci(i)+ri)*cos(t0);
y=(ci(i)+ri)*sin(t0);
circles(i)=plot(x,y,':','color',lineColors);
handles(end+1)=circles(i);
labs(i)=text((ci(i)+ri)*cos(Ang(quad)),(ci(i)+ri)*sin(Ang(quad)),[num2str(ci(i)),'%'],...
'VerticalAlignment',Valign{quad},'HorizontalAlignment',Halign{quad},...
'BackgroundColor',percBg,'FontSize',8);
end
handles=[handles labs];
% calc colors:
if isempty(colors)
cor={};
for j=1:length(Ag)-1
cor{j}=caxcolor(Ag(j),[Ag(1) Ag(end-1)],cmap);
end
else
cor=colors;
end
% fill data:
n=sum(E,2);
if iflip, E=fliplr(E); end
for i=1:length(Ay)-1
if n(i)
t=linspace(Ay(i),Ay(i+1),20)*pi/180;
r1=ri;
for j=1:length(Ag)-1
r2=E(i,j)/n(i) *b(i) +r1;
x=[r1*cos(t(1)) r2*cos(t) r1*cos(fliplr(t))];
y=[r1*sin(t(1)) r2*sin(t) r1*sin(fliplr(t))];
if iflip, jcor=length(Ag)-1-j+1;
else, jcor=j;
end
if E(i,j)>0, handles(end+1)=fill(x,y,cor{jcor}); end
r1=r2;
end
end
end
axis equal
axis off
% uistack has problems in some matlab versions, so:
%uistack(labs,'top')
%uistack(circles,'top')
ch=get(wrAx,'children');
if inorm
% only bring circles up in inorm case.
for i=1:length(circles)
ch(ch==circles(i))=[]; ch=[circles(i); ch];
end
end
for i=1:length(labs)
ch(ch==labs(i))=[]; ch=[labs(i); ch];
end
set(wrAx,'children',ch);
% N S E W labels:
bg='none';
args={'BackgroundColor',bg,'FontSize',8};
h(1)=text(-g-ri, 0,'WEST', 'VerticalAlignment','top', 'HorizontalAlignment','left', args{:});
h(2)=text( g+ri, 0,'EAST', 'VerticalAlignment','top', 'HorizontalAlignment','right',args{:});
h(3)=text( 0,-g-ri,'SOUTH','VerticalAlignment','bottom','HorizontalAlignment','left', args{:});
h(4)=text( 0, g+ri,'NORTH','VerticalAlignment','top', 'HorizontalAlignment','left', args{:});
handles=[handles h];
% scale legend:
L=(g*rl-g-ri)/7;
h=(g+ri)/10;
dy=h/3;
x0=g+ri+(g*rl-g-ri)/7;
x1=x0+L;
y0=-g-ri;
if legType==1 % contimuous.
for j=1:length(Ag)-1
lab=num2str(Ag(j));
if j==1 & hasL & IncHiLow
lab='';
end
y1=y0+h;
handles(end+1)=fill([x0 x1 x1 x0],[y0 y0 y1 y1],cor{j});
handles(end+1)=text(x1+L/4,y0,lab,'VerticalAlignment','middle','fontsize',8);
y0=y1;
end
if ~ (hasH & IncHiLow)
handles(end+1)=text(x1+L/4,y0,num2str(Ag(end)),'VerticalAlignment','middle','fontsize',8);
end
elseif legType==2 % separated boxes.
for j=1:length(Ag)-1
lab=[num2str(Ag(j)) ' - ' num2str(Ag(j+1))];
if j==1 & hasL & IncHiLow
lab=['<',num2str(Ag(2))];
end
if j==length(Ag)-1 & hasH & IncHiLow
lab=['>=',num2str(Ag(j))];
end
y1=y0+h;
handles(end+1)=fill([x0 x1 x1 x0],[y0+dy y0+dy y1 y1],cor{j});
handles(end+1)=text(x1+L/4,(y0+dy+y1)/2,lab,'VerticalAlignment','middle','fontsize',8);
y0=y1;
end
end
% title and legend label:
x=mean([-g*rs,g*rl]);
y=mean([g+ri,g*rs]);
handles(end+1)=text(x,y,titStr,'HorizontalAlignment','center');
x=x0;
y=y1+dy;
handles(end+1)=text(x,y,legStr,'HorizontalAlignment','left','VerticalAlignment','bottom');
if onAxes
place_wr(onAxes,wrAx,onAxesX,onAxesY,onAxesR);
end
if nargout>=1
varargout{1}=handles;
end
if nargout>=2
varargout{2}=E;
end
function place_wr(ax,ax2,x,y,width)
if nargin < 5
width=1/5;
end
uax=get(ax,'units');
pax=get(ax,'position');
set(ax,'units',uax)
axXlim=get(ax,'xlim');
axYlim=get(ax,'ylim');
x_ax2=pax(1)+pax(3)*(x-axXlim(1))/diff(axXlim);
y_ax2=pax(2)+pax(4)*(y-axYlim(1))/diff(axYlim);
pax2=get(ax2,'position');
width=pax(3)*width;
height=pax2(4)*width/pax2(3);
pax2=[x_ax2 y_ax2 width height];
if 1
% place at centre of the wr, not the bottom left corner:
ax2Xlim=get(ax2,'xlim');
ax2Ylim=get(ax2,'ylim');
dx=(0-ax2Xlim(1))/diff(ax2Xlim)*pax2(3);
dy=(0-ax2Ylim(1))/diff(ax2Ylim)*pax2(4);
x_ax2=x_ax2-dx;
y_ax2=y_ax2-dy;
pax2=[x_ax2 y_ax2 width height];
end
set(ax2,'position',pax2)
function cor = caxcolor(val,cax,cmap)
%CAXCOLOR Caxis color for value
% Find the color for a given value in a colormap.
%
% Syntax:
% COLOR = CAXCOLOR(VALUE,CAXIS,COLORMAP)
%
% Inputs:
% VALUE
% CAXIS Default is current caxis
% COLORMAP Default is current colormap
%
% Output:
% COLOR RGB color vector
%
% Example:
% figure
% pcolor(peaks)
% color=caxcolor(0);
% set(gcf,'color',color)
%
if nargin < 3
cmap = get(gcf,'colormap');
end
if nargin < 2
cax = caxis;
end
n=size(cmap,1);
i= (val-cax(1))/diff(cax) * (n-1) +1;
a=i-floor(i);
i=floor(i);
i=min(i,n);
i=max(i,1);
if i==n
cor=cmap(n,:);
elseif i==1
cor=cmap(1,:);
else
cor=cmap(i,:)*(1-a) + cmap(i+1,:)*a;
end

Answers (1)

William Rose
William Rose on 16 Apr 2021

Categories

Find more on Weather and Atmospheric Science in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!