MATLAB Answers

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

5 views (last 30 days)
Jacqueline Rigatto
Jacqueline Rigatto on 12 Apr 2021
Answered: William Rose on 16 Apr 2021
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

Tags

Community Treasure Hunt

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

Start Hunting!