点击上方蓝字和“好玩的MATLAB”一起快乐玩耍吧!/ a, p7 H2 d* Y$ |
wlz4xynft3e6403018843.jpg
! n r1 u# Y" v9 }9 \" ^ A, \* y Z好玩的matlab
% Y( P% k9 ]' t6 V带你解锁不一样的matlab新玩法
& v2 H* F& U* |* T( i' W2 y2 m' V
% N' J+ O# X! n( W" {半个月前有粉丝问我怎么画”风玫瑰图“,之前因为时间比较忙所以没有更新,今天有时间抽空介绍一下“风玫瑰图”的画法,喜欢此推文的小伙伴们记得点赞+关注+分享!【尊重作者劳动成果,转载请注明推文链接和公众号名】
4 Q1 h/ Z+ [3 q t粉丝给的图:! A* W4 ?' ^- A$ o$ ]2 h% _
twqik3xld256403018943.png
9 K. p. y# R4 V- x* u( v
复刻的图:
% O4 o8 i- j+ |4 M) M2 A T" {# D
m3py5nsg2cx6403019043.png
% Q$ x& L) f4 m4 S' ~( y. G其他样式效果: c6 y' o& [. W' Y
qdizkgz15zk6403019144.gif
1 p0 C& A. c4 `# A0 _
( h1 i$ @. b* S5 F# y+ s# l: O }, _% i' b- H3 s
数据数据包含:风向、刮风频率、最大风速、平均风速四个数据。windDirections = [0.0, 22.5, 45.0, 67.5, 90.0, 112.5, 135.0, 157.5, 180.0, 202.5, 225.0, 247.5, 270.0, 292.5, 315.0, 337.5]';windFrequency = [10.2, 4, 4, 3.0, 4.0, 3.0, 4.0, 4.0, 7.0, 6.0, 3, 2, 2, 1.0, 3, 5]';maxWindSpeed = [15, 12, 10, 5, 5, 5,10, 12, 13, 15, 12,5, 5, 10, 12, 15]';avgWindSpeed = [2.8, 2.0, 1.5, 1.2, 1.4, 1.3, 1.45, 2.00, 2.80, 2.80, 1.50, 1.00, 1.0, 1.0, 1.8, 2.0]';data=[windDirections,windFrequency,maxWindSpeed,avgWindSpeed];数据长成这样的
# I S0 {9 ]4 H s% g' |% u- t
vqe31eeaxu46403019244.png
; Q$ u) _; Y8 i" ]3 U x: B& f1 k* F8 u8 k
绘图教程绘制左边Y轴
$ G4 \! b0 r+ F/ H: i P% 设置基础参数maxRadius = ceil(max(windFrequency));minRadius = round(maxRadius / 10);dfT=unique(diff(windDirections));allTheta = 0:0.01:360;% 创建并配置坐标轴fig=figure('Color',[1,1,1]);ax = gca;hold on; box off; grid off; axis equal;ax.YLim = [-maxRadius, maxRadius];ax.YMinorTick = 'on';ax.XColor = 'none';ax.XDir = 'normal';ax.TickDir = 'out';ax.LineWidth = 1.5;majorTicksY = ax.YTick;minorTicksY = (majorTicksY(1:end-1) + majorTicksY(2:end)) / 2;diffTicks = unique(diff(majorTicksY));maxRadius=max(ax.YTick)+diffTicks/2;ax.YLim = [-maxRadius, maxRadius];%重新设定ax.YAxis.MinorTickValues = [minorTicksY(1)-diffTicks, minorTicksY, minorTicksY(end)+diffTicks];ax.YTickLabel = arrayfun(@(y) sprintf('%d', abs(y)), majorTicksY, 'UniformOutput', false);ax.YLabel.String='风向频率(%)';& |+ n& |8 K; t1 i! ~
0n2mwdsmbcl6403019344.png
2 N) H# B& c( R. p' q) S绘制主、次网格和主、次刻度的极坐标区域。
C Y% P: O# U( T3 K- K. r7 [" ~% 绘制主要的极坐标网格线majorRadius = majorTicksY(majorTicksY > minRadius);for i = 1:length(majorRadius) [xMajor, yMajor] = pol2cart(deg2rad(allTheta), majorRadius(i)); plot(xMajor, yMajor, '-', 'Color', [0 0 0], 'LineWidth', 0.5);endmajorTheta = windDirections;fullRadius = linspace(minRadius, maxRadius, 1000);for i = 1:length(majorTheta) [xMajorT, yMajorT] = pol2cart(deg2rad(majorTheta(i)), fullRadius); plot(xMajorT, yMajorT, '-', 'Color', [0.8 0.8 0.8], 'LineWidth', 1.2);end% 绘制次要的极坐标网格线minorRadius = minorTicksY(minorTicksY > minRadius);for i = 1:length(minorRadius) [xMinor, yMinor] = pol2cart(deg2rad(allTheta), minorRadius(i)); plot(xMinor, yMinor, ':', 'Color', [0.55 0.55 0.55], 'LineWidth', 0.8);endminorTheta=windDirections+dfT/2;% minorTheta = 11.25:22.5:360;for i = 1:length(minorTheta) [xMinorT, yMinorT] = pol2cart(deg2rad(minorTheta(i)), fullRadius); plot(xMinorT, yMinorT, '-.', 'Color', [0.55 0.55 0.55]);end% 绘制最外层的极坐标线[xOuter, yOuter] = pol2cart(deg2rad(allTheta), maxRadius);plot(xOuter, yOuter, '-', 'Color', 'k', 'LineWidth', 2);% 主刻度线mainTickTheta= windDirections+dfT;% mainTickTheta = 0:22.5:360;tickRadius = [maxRadius*0.96, maxRadius];for i = 1:length(mainTickTheta) [xMainTick, yMainTick] = pol2cart(deg2rad(mainTickTheta(i)), tickRadius); plot(xMainTick, yMainTick, '-', 'Color', [0, 0, 0], 'LineWidth', 1.5);end% 次刻度线minorTickTheta=windDirections+dfT/2;% minorTickTheta = 11.25:22.5:360;tickRadiusMinor = [maxRadius*0.98, maxRadius];for i = 1:length(minorTickTheta) [xMinorTick, yMinorTick] = pol2cart(deg2rad(minorTickTheta(i)), tickRadiusMinor); plot(xMinorTick, yMinorTick, '-', 'Color', [0 0 0], 'LineWidth', 1.5);end% 添加主刻度外的标签labelDist = maxRadius *(1+ 0.094); % 设定标签距离为最大半径(1+ 0.094),可以根据需要进行调整for i = 1:length(majorTheta) adjustedAngle = majorTheta(i); % 从正北方开始,并且顺时针增加 % 从正北方开始,并且顺时针增加 angle = mod(adjustedAngle, 360); % 确保角度在0-360之间 [xLabel, yLabel] = pol2cart(deg2rad(90-adjustedAngle), labelDist); labelText = sprintf('%.1f°', angle); text(xLabel, yLabel, labelText, 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle');end; G! H' y3 i. T" [4 b
gbt0smlinf06403019444.png
9 s9 L2 Z% g" p5 G
添加刮风数据,添加数据和颜色、图列大小映射关系。adjustedWindDirections = 360 - windDirections;[xWind, yWind] = pol2cart(deg2rad(adjustedWindDirections + 90), windFrequency);colorGradient = [0.0078, 0.0941, 0.7333; 0.9725, 0.0039, 0.5216];colorMapMajor = makeColorMap(colorGradient, length(windDirections));% 根据风速大小对颜色进行排序[~, idx] = sort(maxWindSpeed, 'Ascend');sortedColorMap = colorMapMajor(idx, :);% 对于相同的风速值,使用第一个出现的颜色值为其赋色uniqueSpeeds = unique(maxWindSpeed, 'stable');for i = 1:length(uniqueSpeeds) currentSpeed = uniqueSpeeds(i); indices = find(maxWindSpeed == currentSpeed); if length(indices) > 1 sortedColorMap(indices, :) = repmat(sortedColorMap(indices(1), :), length(indices), 1); endendmaxWind = max(maxWindSpeed);desiredMaxSize=max(avgWindSpeed);desiredMinSize=min(avgWindSpeed);for i = 1:length(windDirections) color = getColorForSpeed(maxWindSpeed(i), maxWind , colorMapMajor); s = mapToMarkerSize(avgWindSpeed(i), desiredMaxSize, desiredMinSize); plot(xWind(i), yWind(i), 'o', 'LineWidth', 1.2, 'MarkerSize',s, ... 'MarkerEdgeColor', 'k', 'MarkerFaceColor', color);end# H. A3 o- j$ t/ z( a. A
qb54jn2mwb06403019544.png
7 r& c2 v: y- b# J% @3 n* m颜色条绘制$ r* S: ^( M i5 G% S$ c: F
colorMapMinor = makeColorMap(colorGradient, 10);colormap(colorMapMinor);cBar = colorbar;cBar.Position = [.9 .1 .04 .36];cBar.LineWidth = 1.2;cBar.TickLength = 0.025;cBar.Ticks = linspace(floor(min(maxWindSpeed)),ceil(max(maxWindSpeed)),11);% cBar.Ticks =linspace(minWindSpeed, maxWindSpeed, 11);tickLabels = arrayfun(@(x) sprintf('%.1f', x), cBar.Ticks, 'UniformOutput', false);cBar.TickLabels = tickLabels;cBar.TickDirection = 'both';colorBarTitle = title(cBar, '最大风速(m/s)');caxis([floor(min(maxWindSpeed)),ceil(max(maxWindSpeed))]);AxSize=axes(fig,'Position',[.86 0.55 .1 .36],'Color',[1,1,1]);title(AxSize,'平均风速(m/s)')AxSize.XColor='none';AxSize.YColor='none';meanRLabel=linspace(ceil(0.3),ceil(2.6),5);
. A# R+ v( e1 C/ E8 e' V- e
lzwtn2u1ejq6403019644.png
1 G" O+ a8 A& i# A# P5 F添加图列绘制# H x: ~0 \; {
% 定义半径和距离legR=linspace(ceil(min(avgWindSpeed)),ceil(max(avgWindSpeed)),5);d =ceil(ceil(max(avgWindSpeed))/2);% 计算每个圆的中心位置legY = zeros(1, length(legR));totalHeight = sum(2.*legR) + d*(length(legR)-1);legY(1) = totalHeight/2 - legR(1);for i = 2:length(legR) legY(i) = legY(i-1) - 2*legR(i-1) - d;end% 绘制圆形hold on;for i = 1:length(legR) rectangle('Position',[-legR(i), legY(i)-legR(i), 2*legR(i), 2*legR(i)], 'Curvature', [1, 1],'LineWidth',1); text(max(legR) + 0.6, legY(i), sprintf('%.1f', legR(i)));endaxis equal;xlim([-max(legR) max(legR)]);ylim([legY(end)-legR(end) legY(1)+legR(1)]);hold off; Q5 n, N% `3 D2 a- B
kw25fxaqzyu6403019745.png
1 X, S/ Y) X! W {) T! k' ~6 g4 }1 s8 D% y
绘图工具箱介绍默认绘图
' }, R$ S3 t# A" o& N3 C; Ufigure('name','默认绘图')w=WindRosePlot(data);w.plot();
/ [& g8 Q7 B/ S/ N$ V+ H% Y/ _' x( V P
刻度颜色设置figure('name','设置刻度颜色')w=WindRosePlot(data);w.AxisColor=[0,0,1];w.AxisLineWidth=2;w.plot();
) s0 Z( z/ K# {" y: K& x
be0qars44nu6403019845.png
6 n% r1 M8 d% z7 K1 M刻度方向和长短设置,其中刻度方向有:'in'|'out'|'both'?。figure('name','设置刻度方向、长短')w=WindRosePlot(data);w.AxisMainTickDir='both';w.AxisMinorTickDir='out';w.AxisColor=[1,0,0];w.AxisLineWidth=2;w.AxisTickLength=0.08;w.plot();8 x' L1 a7 J0 [3 b5 K( E% L
3ko00z1pm4s6403019945.png
D- B( N: F, o( @7 E
网格设置:主、次网格的颜色、粗细、透明度设置。figure('name','主、次网格样式、颜色、粗细、透明度')w=WindRosePlot(data);w.RGrid='on';w.RGridLineStyle='-.';w.RGridColor=[1,0,0];w.RGridAlpha=0.5;w.RGridLineWidth=1.5;* z' |, O( @: s! ^ k
w.ThetaGrid='on';w.ThetaGridLineStyle='--';w.ThetaGridColor=[0,1,0];w.ThetaGridAlpha=0.5;w.ThetaGridLineWidth=2;
$ I9 B+ F3 m- k T( m8 p Yw.MinorRGrid='on';w.MinorRGridLineStyle='-';w.MinorRGridColor=[1,1,0]; C' E1 z, c+ \0 Z+ @" A
w.MinorThetaGrid='on';w.MinorThetaGridLineStyle=':';w.MinorThetaGridColor=[0,0,1];w.plot();- L6 b6 J# o; W$ }! Y p- O: L
5cz354cpbkg6403020045.png
5 X% B1 W; ^3 X3 ~9 A2 ~/ _0 w, q
背景颜色设置figure('name','背景颜色')w=WindRosePlot(data);w.ColorMaps=hsv;w.AxisBackgroundColor=[1,1,1]*0.10;w.AxisFaceAlpha=0.1;w.plot();( K4 D6 B1 \& r
ylcptuxo4l56403020145.png
8 X% g0 D: | @6 \* ~' l! w
图列设置figure('name','图列设置:title设置、背景色、边缘色、边缘粗细、字体属性')w=WindRosePlot(data);w.LegendTitle='图列设置Title';w.LegendBackgroundColor=[1,.9,.8]*.98;w.LegendEdgeColor='m';w.LegendLineWidth=4;w.LegendFontName='Times new Roman';w.LegendFontSize=16;w.LegendFontAngle='normal';w.LegendFontWeight='bold';%加粗w.plot();
) p# }) M1 r \, G% e6 o
qcu1sfxt2o46403020246.png
7 r! a0 T M {, M3 E- v* M颜色条设置
1 U' _9 f6 F ^7 l. Dfigure('name','颜色条设置')w=WindRosePlot(data);% load('colorsData/acton100.mat')% load('colorsData/bwr.mat')% load('colorsData/vikO100.mat')% w.ColorMaps=colorsList;% w.ColorMaps=hsv;% w.ColorMaps=bone;% w.ColorMaps=jet;% w.ColorMaps=winter;w.ColorMaps=spring;w.ColorMapsTitle='颜色条 Title测试';w.ColorMapsFontSize=14;w.ColorMapsFontAngle='italic';w.plot();/ Z/ e2 e3 R! G5 N
e11til1i2fp6403020346.png
, h. `; `* u& ^( n
|
+ _) o& ^5 q6 t1 M4 M& p$ \6 h! F. P
yq4t2poz4em6403020446.png
3 z4 s. g5 Q6 a2 A+ L |
: {+ L9 X5 Y0 k* Y
50tc14r2wzu6403020546.png
* f( x$ _0 I* Z g" J
|
+ i$ b. G6 u, O7 t) J9 k
pmu50c4vltf6403020646.png
* @( T5 A9 W: K: Y) _8 V$ C) H, k |
; C$ @ @6 V! i
fyp0n5kt0ap6403020746.png
, f1 g i5 Q8 J- D0 M
| 4 j4 L0 x7 e, ^' x/ T
* @+ [. m. `- d4 M' ]$ G/ L
| WindRosePlot类函数收藏=学会
: G, @ B8 n( Zclassdef WindRosePlot % ------------------------------------------------ % @Author: 好玩的 MATLAB. % @E-mail: 2377389590@qq.com % @WeChat: idmatlab % @Date: Oct 30, 2023. % @Version: Matlab R2022b. % % #Respect the fruits of labor. Please note the tweet link and official account name when reprinting. Commercial use is strictly prohibited. % Example: % windDirections = [0.0, 22.5, 45.0, 67.5, 90.0, 112.5, 135.0, 157.5, 180.0, 202.5, 225.0, 247.5, 270.0, 292.5, 315.0, 337.5]'; % windFrequency = [10.2, 4, 4, 3.0, 4.0, 3.0, 4.0, 4.0, 7.0, 6.0, 3, 2, 2, 1.0, 3, 5]'; % maxWindSpeed = [15, 12, 10, 5, 5, 5,10, 12, 13, 15, 12,5, 5, 10, 12, 15]'; % avgWindSpeed = [2.8, 2.0, 1.5, 1.2, 1.4, 1.3, 1.45, 2.00, 2.80, 2.80, 1.50, 1.00, 1.0, 1.0, 1.8, 2.0]'; % % dataT = table(windDirections, windFrequency, maxWindSpeed, avgWindSpeed, 'VariableNames', {'风向', '频率', '最大风速', '平均风速'}); % data=[windDirections,windFrequency,maxWindSpeed,avgWindSpeed]; % w=WindRosePlot(data); % w.plot(); %------------------------------------------------- properties fig % WindDirections; %风向 WindFrequency; %刮风频率 MaxWindSpeed; %最大风速 AvgWindSpeed; %平均风速 % RGrid='on'; %显示主 r 轴网格线 ThetaGrid='on'; %显示主 Theta 轴网格线 MinorRGrid='on'; %显示次 r 轴网格线 MinorThetaGrid='on';%显示次 Theta 轴网格线 % YLabel='风向频率(%)'; % R主网格样式 RGridLineStyle='-'; RGridColor=[0,0,0]; RGridAlpha=1; RGridLineWidth=0.5; % Theta 主网格样式 ThetaGridLineStyle='-'; ThetaGridColor=[0.8 0.8 0.8]; ThetaGridAlpha=1; ThetaGridLineWidth=1.2; % R次网格样式 MinorRGridLineStyle=':'; MinorRGridColor=[0.55 0.55 0.55]; MinorRGridAlpha=1; MinorRGridLineWidth=0.8; % Theta 次网格样式 MinorThetaGridLineStyle='-.' MinorThetaGridColor=[0.55 0.55 0.55]; MinorThetaGridAlpha=1; MinorThetaGridLineWidth=1.2; % 刻度样式 AxisColor=[0,0,0]; AxisLineWidth=1.5; AxisMainTickDir='in'; AxisMinorTickDir='in'; AxisTickLength=0.04; AxisTickFontSize=12; AxisTickFontWeight='normal'%'normal'|'bold' AxisTickFontName='Times new Roman'; AxisFaceAlpha=0.5; AxisBackgroundColor=[1,1,1]; % 颜色条 ColorMaps=[0.0078, 0.0941, 0.7333; 0.9725, 0.0039, 0.5216]; ColorMapsTitle='最大风速(m/s)'; ColorMapsFontName='Times new Roman'; ColorMapsFontSize=12; ColorMapsFontAngle='normal';%'normal' | 'italic'。 ColorMapsFontWeight='normal'; %'normal'|'bold' %legend 图列 LegendTitle='平均风速(m/s)'; LegendBackgroundColor=[1,1,1]*.95; LegendEdgeColor='none'; LegendLineWidth=1; LegendFontName='Times new Roman'; LegendFontAngle='italic';%'normal' | 'italic'。 LegendFontSize=12; LegendFontWeight='normal'; LegendRotation=0; end methods function obj =WindRosePlot(data) obj.fig=gcf; obj.fig.Color=[1,1,1]; obj.WindDirections = data(:,1); obj.WindFrequency = data(:,2); obj.MaxWindSpeed = data(:,3); obj.AvgWindSpeed =data(:,4); %------------------------- obj.RGrid='on'; obj.RGridLineStyle='-'; obj.RGridColor=[0,0,0]; obj.RGridAlpha=1; obj.RGridLineWidth=0.5; obj.ThetaGrid='on'; obj.ThetaGridLineStyle='-'; obj.ThetaGridColor=[0.8 0.8 0.8]; obj.ThetaGridAlpha=1; obj.ThetaGridLineWidth=1.2; obj.MinorRGrid='on'; obj.MinorRGridLineStyle=':'; obj.MinorRGridColor=[0.55 0.55 0.55]; obj.MinorRGridAlpha=1; obj.MinorRGridLineWidth=0.8; obj.MinorThetaGrid='on';obj.MinorThetaGridLineStyle='-.';obj.MinorThetaGridColor=[0.55 0.55 0.55];obj.MinorThetaGridAlpha=1;obj.MinorThetaGridLineWidth=1.2; obj.ColorMaps = [0.0078, 0.0941, 0.7333; 0.9725, 0.0039, 0.5216]; end function plot(obj) maxRadius = ceil(max(obj.WindFrequency)); minRadius = round(maxRadius / 10); dfT=unique(diff(obj.WindDirections)); allTheta = 0:0.01:360; ax = gca; hold on; box off; grid off; axis equal; ax.YLim = [-maxRadius, maxRadius]; ax.YMinorTick = 'on'; ax.XColor = 'none'; ax.XDir = 'normal'; ax.TickDir = 'out'; ax.LineWidth = obj.AxisLineWidth; ax.YColor=obj.AxisColor; majorTicksY = ax.YTick; minorTicksY = (majorTicksY(1:end-1) + majorTicksY(2:end)) / 2; diffTicks = unique(diff(majorTicksY)); maxRadius=max(ax.YTick)+diffTicks/2; ax.YLim = [-maxRadius, maxRadius];%重新设定 ax.YAxis.MinorTickValues = [minorTicksY(1)-diffTicks, minorTicksY, minorTicksY(end)+diffTicks]; ax.YTickLabel = arrayfun(@(y) sprintf('%d', abs(y)), majorTicksY, 'UniformOutput', false); ax.YLabel.String=obj.YLabel; % =============绘制主要R Theta的极坐标网格线=============================== % # RGrid majorRadius = majorTicksY(majorTicksY > minRadius); if strcmpi(obj.RGrid,'on') for i = 1:length(majorRadius) [xMajor, yMajor] = pol2cart(deg2rad(allTheta), majorRadius(i)); plot(xMajor, yMajor,'LineStyle',obj.RGridLineStyle,'Color', [obj.RGridColor obj.RGridAlpha], 'LineWidth',obj.RGridLineWidth); end elseif strcmpi(obj.RGrid,'off') end % # ThetaGrid majorTheta = obj.WindDirections; fullRadius = linspace(minRadius, maxRadius, 1000); if strcmpi(obj.ThetaGrid,'on') for i = 1:length(majorTheta) [xMajorT, yMajorT] = pol2cart(deg2rad(majorTheta(i)), fullRadius); plot(xMajorT, yMajorT, 'LineStyle',obj.ThetaGridLineStyle, 'Color', [obj.ThetaGridColor obj.ThetaGridAlpha], 'LineWidth', obj.ThetaGridLineWidth); end elseif strcmpi(obj.ThetaGrid,'off') end % 绘制次要R Theta的极坐标网格线 % # MinorRGrid if strcmpi(obj.MinorRGrid,'on') minorRadius = minorTicksY(minorTicksY > minRadius); for i = 1:length(minorRadius) [xMinor, yMinor] = pol2cart(deg2rad(allTheta), minorRadius(i)); plot(xMinor, yMinor, 'LineStyle',obj.MinorRGridLineStyle,'Color', [obj.MinorRGridColor obj.MinorRGridAlpha], 'LineWidth',obj.MinorRGridLineWidth); end elseif strcmpi(obj.MinorRGrid,'off') end % # MinorThetaGrid minorTheta=obj.WindDirections+dfT/2; if strcmpi(obj.MinorThetaGrid,'on') for i = 1:length(minorTheta) [xMinorT, yMinorT] = pol2cart(deg2rad(minorTheta(i)), fullRadius); plot(xMinorT, yMinorT, 'LineStyle',obj.MinorThetaGridLineStyle, 'Color', [obj.MinorThetaGridColor obj.MinorThetaGridAlpha], 'LineWidth', obj.MinorThetaGridLineWidth); end elseif strcmpi(obj.MinorThetaGrid,'off') end % ===================绘制刻度=============================== % 绘制最外层的极坐标线 [xOuter, yOuter] = pol2cart(deg2rad(allTheta), max(ax.YTick)+diffTicks/2); plot(xOuter, yOuter, '-', 'Color',obj.AxisColor, 'LineWidth', obj.AxisLineWidth); fill(xOuter, yOuter,obj.AxisBackgroundColor,'EdgeColor','none','FaceAlpha',obj.AxisFaceAlpha) % #主刻度 if obj.AxisTickLength > 1 || obj.AxisTickLength 0 error('TickLength must be less than 1 and greater than 0.'); end if strcmpi(obj.AxisMainTickDir,'in') tickRadius = [maxRadius*(1-obj.AxisTickLength), maxRadius]; elseif strcmpi(obj.AxisMainTickDir,'out') tickRadius = [ maxRadius,maxRadius*(1+obj.AxisTickLength)]; elseif strcmpi(obj.AxisMainTickDir,'both') tickRadius = [maxRadius*(1-obj.AxisTickLength) maxRadius*(1+obj.AxisTickLength)]; else error('Invalid value for mainTickDir. It should be "in", "out", or "both".'); end mainTickTheta= obj.WindDirections+dfT; for i = 1:length(mainTickTheta) [xMainTick, yMainTick] = pol2cart(deg2rad(mainTickTheta(i)), tickRadius); plot(xMainTick, yMainTick, '-', 'Color', obj.AxisColor, 'LineWidth', obj.AxisLineWidth); end disp(char([20844 20247 21495 58 22909 29609 30340 77 97 116 108 97 98])) % #次刻度 if strcmpi(obj.AxisMinorTickDir,'in') tickRadiusMinor = [maxRadius*(1-obj.AxisTickLength/2), maxRadius]; elseif strcmpi(obj.AxisMinorTickDir,'out') tickRadiusMinor = [ maxRadius maxRadius*(1+obj.AxisTickLength/2)]; elseif strcmpi(obj.AxisMinorTickDir,'both') tickRadiusMinor = [maxRadius*(1-obj.AxisTickLength/2), maxRadius*(1+obj.AxisTickLength/2)]; else error('Invalid value for mainTickDir. It should be "in", "out", or "both".'); end minorTickTheta=obj.WindDirections+dfT/2; for i = 1:length(minorTickTheta) [xMinorTick, yMinorTick] = pol2cart(deg2rad(minorTickTheta(i)), tickRadiusMinor); plot(xMinorTick, yMinorTick, '-', 'Color', obj.AxisColor, 'LineWidth', obj.AxisLineWidth*0.8); end % ==========添加主刻度外的标签=========================== labelDist = maxRadius *(1+ 0.094); % 设定标签距离为最大半径(1+ 0.094),可以根据需要进行调整 for i = 1:length(majorTheta) adjustedAngle = majorTheta(i); % 从正北方开始,并且顺时针增加 % 从正北方开始,并且顺时针增加 angle = mod(adjustedAngle, 360); % 确保角度在0-360之间 [xLabel, yLabel] = pol2cart(deg2rad(90-adjustedAngle), labelDist); labelText = sprintf('%.1f°', angle); text(xLabel, yLabel, labelText, 'HorizontalAlignment', 'center', ... 'VerticalAlignment', 'middle', ... 'FontSize',obj.AxisTickFontSize,'FontWeight',obj.AxisTickFontWeight,'FontName',obj.AxisTickFontName, ... 'Color',obj.AxisColor); end %==================添加数据======================== adjustedWindDirections = 360 - obj.WindDirections; [xWind, yWind] = pol2cart(deg2rad(adjustedWindDirections + 90), obj.WindFrequency); colorMapMajor = makeColorMap(obj.ColorMaps, length(obj.WindDirections)); % 根据风速大小对颜色进行排序 [~, idx] = sort(obj.MaxWindSpeed, 'Ascend'); sortedColorMap = colorMapMajor(idx, :); %对于相同的风速值,使用第一个出现的颜色值为其赋色 uniqueSpeeds = unique(obj.MaxWindSpeed, 'stable'); for i = 1:length(uniqueSpeeds) currentSpeed = uniqueSpeeds(i); indices = find(obj.MaxWindSpeed == currentSpeed); if length(indices) > 1 sortedColorMap(indices, :) = repmat(sortedColorMap(indices(1), :), length(indices), 1); end end maxWind = max(obj.MaxWindSpeed); desiredMaxSize=max(obj.AvgWindSpeed); desiredMinSize=min(obj.AvgWindSpeed); for i = 1:length(obj.WindDirections) color = obj.getColorForSpeed(obj.MaxWindSpeed(i), maxWind , colorMapMajor); s = obj.mapToMarkerSize(obj.AvgWindSpeed(i), desiredMaxSize, desiredMinSize); plot(xWind(i), yWind(i), 'o', 'LineWidth', 1.2, 'MarkerSize',s,... 'MarkerEdgeColor', 'k', 'MarkerFaceColor', color); end % ================添加 colorbar====================================== colorMapMinor = makeColorMap(obj.ColorMaps, 10); colormap(colorMapMinor); cBar = colorbar; cBar.Position = [.9 .1 .04 .36]; cBar.LineWidth = 1.2; cBar.TickLength = 0.025; cBar.Ticks = linspace(floor(min(obj.MaxWindSpeed)),ceil(max(obj.MaxWindSpeed)),11); tickLabels = arrayfun(@(x) sprintf('%.1f', x), cBar.Ticks, 'UniformOutput', false); cBar.TickLabels = tickLabels; cBar.TickDirection = 'both'; caxis([floor(min(obj.MaxWindSpeed)),ceil(max(obj.MaxWindSpeed))]); title(cBar, obj.ColorMapsTitle); cBar.FontName= obj.ColorMapsFontName; cBar.FontSize=obj.ColorMapsFontSize; cBar.FontAngle= obj.ColorMapsFontAngle; cBar.FontWeight=obj.ColorMapsFontWeight; %'normal'|'bold' % ===============添加 Legend======================================= legAx=axes(obj.fig,'Position',[.86 0.55 .1 .36],'Color',[1,1,1],'Box','on'); title(legAx,obj.LegendTitle) legAx.Color=obj.LegendBackgroundColor; legAx.XColor=obj.LegendEdgeColor;legAx.YColor=obj.LegendEdgeColor; legAx.XTick=[];legAx.YTick=[]; legAx.TickLength=[0 0]; legAx.LineWidth=obj.LegendLineWidth; % 定义半径和距离 legR=linspace(ceil(min(obj.AvgWindSpeed)),ceil(max(obj.AvgWindSpeed)),5); d =ceil(ceil(max(obj.AvgWindSpeed))/2); legY = zeros(1, length(legR)); totalHeight = sum(2.*legR) + d*(length(legR)-1); legY(1) = totalHeight/2 - legR(1); for i = 2:length(legR) legY(i) = legY(i-1) - 2*legR(i-1) - d; end % 绘制圆形 hold on; for i = 1:length(legR) rectangle('Position',[-legR(i), legY(i)-legR(i), 2*legR(i), 2*legR(i)], 'Curvature', [1, 1],'LineWidth',1.5,'FaceColor', 'white'); text(max(legR) + 0.9, legY(i), sprintf('%.1f', legR(i)), ... "FontName",obj.LegendFontName,"FontSize",obj. LegendFontSize,'FontAngle',obj.LegendFontAngle, ... 'FontWeight',obj.LegendFontWeight,'Rotation',obj.LegendRotation); end axis equal; xlim([-max(legR)*1.2 max(legR)*1.2]); ylim([(legY(end)-legR(end))*1.1 (legY(1)+legR(1))*1.1]); hold off; end end methods(Access=private) function color = getColorForSpeed(obj,speed, maxSpeed, colorMap) idx = round((speed / maxSpeed) * size(colorMap, 1)); idx = min(max(idx, 1), size(colorMap, 1)); % 保证idx在正确的范围内 color = colorMap(idx, :); end function s = mapToMarkerSize(obj,speed, maxSize, minSize) normalized = (speed - minSize)/(maxSize -minSize); s = minSize + normalized * (maxSize - minSize); s=s*10; end endend属性:fig:存储图形的句柄。
, b1 B. t: U \- M( n) J7 q9 TWindDirections:风向数据。
+ L1 _1 U6 |$ G5 |- A- iWindFrequency:刮风频率。! m% O, y# V% b! t" |
MaxWindSpeed:最大风速数据。
' U3 W, l& O, m4 JAvgWindSpeed:平均风速数据。
8 |2 Y+ _* n4 n: D4 xRGrid,ThetaGrid,MinorRGrid,MinorThetaGrid:这些属性用于控制是否显示对应的网格线。* Q: b, b$ w Z2 T9 `& ^$ F
YLabel:Y轴标签。7 ]& L M0 c8 E" C7 V( r
还有许多其他的属性,例如RGridLineStyle,RGridColor等,用于控制图形的样式和外观。
& {: O6 F) L* }% I4 _方法:构造函数WindRosePlot:当创建WindRosePlot类的对象时,此构造函数将被调用。构造函数接收风玫瑰数据作为输入,并初始化类的属性。此外,还设置了默认的图形样式。
* _" U3 R& {% }6 @3 v* Aplot方法:这个方法用于绘制风玫瑰图。它首先设置坐标轴和极坐标的属性。接下来,它会绘制主要和次要的R和Theta网格线。然后,它绘制刻度。
. h$ D) _. n) ]
' }8 U) Z& q0 M6 W; j! K[/ol]- -THE END- -
) j3 I! g K- T, a源码下载:gitee下载:https://gitee.com/iDMatlab/wind-rose-plot
( P4 |) i1 D' p% c+ p( A
' T% Z2 R8 I: E, }2 C- EQQ 群下载
) Z" s6 z: x# w
1 [3 u9 n( F [5 L& Q! Q* m: W! e; y/ L, M
1 ?, B; Q6 @* P' b i+ K* \+ v
G8 ]* E4 f+ l% }
) y. h. b' ~: b* K- y
送书活动
8 L. X. l" x; O, |" s ' S' a P2 y' v) k

2 g5 F( e0 e& e- C% C7 Z& Y
8 S T7 ~* \5 i+ L+ o$ {包邮赠送 「北京大学出版社」赞助《AI时代程序员开发之道》和《AI时代项目经理成长之道》本书《AI时代程序员开发之道》:知识精进+重点解析+上机实训+综合实战+ChatGPT应用,零基础入门,让程序员插上翅膀高效开发!本书《AI时代项目经理成长之道》:1.开发新模式:让项目管理更高效、更快捷、更完美。 2.全流程解析:涵盖ChatGPT的不同应用场景,从编写各种文档,到组建高效团队、辅助项目沟通管理、计划管理、时间管理、质量管理等使用ChatGPT进行程序开发的关键技巧。 3.实战检验:ChatGPT结合多种项目管理工具及案例实操讲解,理解更加透彻。 4.100%提高开发效率:揭秘ChatGPT与项目管理工作高效融合的核心方法论和实践经验。 5.超值资源:免费赠送全书案例源文件、教学视频及配套工具,供读者下载学习。
& _% Z! V- L" e' ~- N+ R [# w! o V: |( b/ W$ @6 x
* q* L; x, J% s, s) h& y【抽奖方式及满足条件】:
& q! f' O# }9 p1.关注「好玩的MATLAB 」公众号和视频号# i* S, w* ?% K- x" i2 I

+ t0 z6 C- }, s a3 M2 A) X2.给本文点【赞】+【在看】;+ g$ m: w% c' E
3.留言区评论点赞最多的前3名。( {5 a6 f t5 S" C; E2 }5 c4 _
4.本活动只针对从未获过奖的同学,之前获过奖的小伙伴,不用参加。
7 A1 O' N# n8 V9 b8 m0 X9 ~同时满足上述4个条件的读者朋友,包邮赠送一本书。
1 b5 t# J. y; t7 |【开奖时间】:2023年10月31日夜晚8点+ Z1 \. h: N% y
【领奖方式】:在开奖时加小编私人微信:idmatlab4 ~. {9 j) ^' ^1 Y
: M* W$ u" z1 Q6 m. B( a6 k扫一扫加管理员微信4 v, V) {+ _/ n3 ]
6 u4 f# V$ b6 ~
 |