Polarhistorgram color by coordinate

2 views (last 30 days)
Abigail Hobbs
Abigail Hobbs on 4 Mar 2025
Edited: dpb on 4 Mar 2025
I am working on generating wind roses - I have been able to get a nice wind rose where I can color the bars by wind speed, but is there a way to also color or change the transparency based on the polar sector? Example: 0-90 deg would be green, 90-180 blue, etc. I have been trying to figure this part out. Thank you! I have included an example data file and my code so far.
%% Used corrected wind direction from weather station, and then used average of the two relative wind speeds since there was not a corrected wind direction
wind_directionTB=weatherdata011125(:,3); wind_direction=table2array(wind_directionTB);
wind_speedTB=weatherdata011125(:,2); wind_speed=table2array(wind_speedTB);
figure
pax = polaraxes;
%polarhistogram(deg2rad(wind_direction((wind_speed<20 & wind_speed>15))),deg2rad(0:10:360),'FaceColor','red','FaceAlpha',1,'displayname','15 - 20 m/s')
polarhistogram(deg2rad(wind_direction((wind_speed<15))),deg2rad(0:10:360),'FaceColor','#A2142F','FaceAlpha',1,'displayname','10 - 15 m/s')
hold on
polarhistogram(deg2rad(wind_direction((wind_speed<10))),deg2rad(0:10:360),'FaceColor','#D95319','FaceAlpha',1,'displayname','8 - 10 m/s')
polarhistogram(deg2rad(wind_direction((wind_speed<8))),deg2rad(0:10:360),'FaceColor','#EDB120','FaceAlpha',1,'displayname','4 - 8 m/s')
polarhistogram(deg2rad(wind_direction((wind_speed<4))),deg2rad(0:10:360),'FaceColor','#0072BD','FaceAlpha',1,'displayname','2 - 4 m/s')
polarhistogram(deg2rad(wind_direction((wind_speed<2))),deg2rad(0:10:360),'FaceColor','#4DBEEE','FaceAlpha',1,'displayname','< 2 m/s')
legend('show')
pax.ThetaDir = 'clockwise';
pax.ThetaZeroLocation = 'top';
% title('Wind Rose')
% set(gca,'thetagrid','off')
% set(gca,'thetaticklabels',{' '})
% set(gca,'rticklabels',{' '})
set(gcf,'ren','painters')

Answers (2)

dpb
dpb on 4 Mar 2025
Edited: dpb on 4 Mar 2025
w=warning("off",'MATLAB:table:ModifiedAndSavedVarnames'); % turn of nag warning on variable naming
tWD=readtable('weather_data_01_11_25.csv'); % use generic variable names
warning(w)
head(tWD) % see what's in it since we don't know
Time RelativeWindSpeed_m_s_ WindDirection_Degrees_ Temperature_C_ RH SolarRadiaton_W_m__2__ Precipitation_mm_ ____________________ ______________________ ______________________ ______________ ___ ______________________ _________________ 11-Jan-2025 00:08:30 3.02 135 6.6 99 1 0.6 11-Jan-2025 00:13:31 4.23 137 6.9 100 1 0.6 11-Jan-2025 00:18:32 3.72 150 7.2 99 1 0.6 11-Jan-2025 00:23:33 3.18 123 7.6 100 1 0.6 11-Jan-2025 00:28:34 3.87 157 8 100 1 0.6 11-Jan-2025 00:33:35 3.6 144 9.1 100 0 0.6 11-Jan-2025 00:38:35 3.89 149 9.7 100 0 0.6 11-Jan-2025 00:43:38 4.69 157 10 100 1 0.6
tWD.Properties.VariableNames(2:4)={'WindSpeed','WindDirection','Temperature'}; % more convenient names
tWD=addvars(tWD,deg2rad(tWD.WindDirection),'After','WindDirection','NewVariableNames','WindRadians');
figure
hPax=polaraxes('ThetaDir','clockwise','ThetaZeroLocation','top');
hold(hPax,'on')
ALPHA=0.05; % face alpha for background -- set as result pleases
BKGD='gcbm'; % character string for background color cycle -- adapt to suit...
edges=[0 1/2]; % initial 90 degree wedge
MAX=40; % arbitrary max from initial windrose--have to fix to match other data
for i=1:numel(BKGD) % iterate over colors
polarhistogram('BinEdges',pi*edges,'BinCounts',MAX,'FaceColor',BKGD(i),'FaceAlpha',ALPHA,'EdgeColor','none','displayname','')
edges=edges+(1/2); % next quadrant
end
edges=deg2rad(0:10:360); % reset for real thing
FACES={'#A2142F','#D95319','#EDB120','#0072BD','#4DBEEE'};
BINS=[15 10 8 4 2 0];
for i=1:numel(BINS)-1
LABEL=sprintf('%d - %d m/s',BINS(i),BINS(i+1));
polarhistogram(tWD.WindRadians(tWD.WindSpeed<BINS(i)),edges,'FaceColor',FACES{i},'displayname',LABEL)
end
Try something like the above for starters -- you have to draw the background as more sections because the axes color is only a single property.
The scaling for the background will have to be set dynamically from the data; I just looked at the original figure to get the value "40" above.
I also took the opportunity to make the code more generic so it can be applied to any similar dataset without the baggage of the date -- that's in the dataset; don't carry metadata around with the filenames.
I the also showed how to make more convenient names in the table to suit and made the second dataset of the wind direction in radians to only do the conversion once.
Another nicety that could be done would be to set the bin magnitudes in a data array along with their associated color values and then iterate over the number of bins in a loop rather than duplicating the same line of code over and over. Generically, this might mean adding another function that set bin sizes/magnitudes to be able to handle any data set with different ranges.
And, of course, finish up the original task by picking another pair of colors to draw in the backgrounds...there again, a loop construct would be good way to implement.
ADDENDUM:
Oh! Forgot to add -- you'll want to save an array of handles to the histogram objects so that when you add the legend (another place where the string could/should be generated dynamically from the binning values instead of having hardcoded) you can pass only the actual data handles; otherwise it's going to have extra labels for the background areas; the 'Annotation' property is read-only so even if the 'DisplayName' is blank, you'll still get the legen colored box, it just won't have a label associated with it. Pass the array of wanted legend objects to legend only.

Voss
Voss on 4 Mar 2025
Since histogram objects only support one FaceColor and one FaceAlpha value for all faces, it's necessary to create one histogram per sector and set each histogram's properties as required. Here's an example where FaceAlpha varies from 0.9 (in sector 0-90 degrees) down to approx. 0.1 (in sector 270-360 degrees) with a decrement of 0.2667.
weatherdata011125 = readtable('weather_data_01_11_25.csv');
Warning: Column headers from the file were modified to make them valid MATLAB identifiers before creating variable names for the table. The original column headers are saved in the VariableDescriptions property.
Set 'VariableNamingRule' to 'preserve' to use the original column headers as table variable names.
wind_direction = weatherdata011125{:,3};
wind_speed = weatherdata011125{:,2};
edges = deg2rad(0:10:360);
figure
pax = polaraxes('ThetaDir','clockwise','ThetaZeroLocation','top','NextPlot','add');
h = gobjects(4,5);
for ii = 1:4
idx = wind_direction >= (ii-1)*90 & wind_direction < ii*90;
face_alpha = 0.9-0.2667*(ii-1);
h(ii,:) = [ ...
polarhistogram(deg2rad(wind_direction(idx & wind_speed<15)),edges,'FaceColor','#A2142F','FaceAlpha',face_alpha,'displayname','10 - 15 m/s')
polarhistogram(deg2rad(wind_direction(idx & wind_speed<10)),edges,'FaceColor','#D95319','FaceAlpha',face_alpha,'displayname','8 - 10 m/s')
polarhistogram(deg2rad(wind_direction(idx & wind_speed<8)),edges,'FaceColor','#EDB120','FaceAlpha',face_alpha,'displayname','4 - 8 m/s')
polarhistogram(deg2rad(wind_direction(idx & wind_speed<4)),edges,'FaceColor','#0072BD','FaceAlpha',face_alpha,'displayname','2 - 4 m/s')
polarhistogram(deg2rad(wind_direction(idx & wind_speed<2)),edges,'FaceColor','#4DBEEE','FaceAlpha',face_alpha,'displayname','< 2 m/s')
];
end
legend(h(1,:))
get(h,'FaceAlpha')
ans = 20x1 cell array
{[0.9000]} {[0.6333]} {[0.3666]} {[0.0999]} {[0.9000]} {[0.6333]} {[0.3666]} {[0.0999]} {[0.9000]} {[0.6333]} {[0.3666]} {[0.0999]} {[0.9000]} {[0.6333]} {[0.3666]} {[0.0999]}

Categories

Find more on Polar Plots in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!