MATLAB|风玫瑰图

目录

扫一扫关注公众号

效果图

粉丝给的图:

复刻的图:

其他样式效果:

数据

绘图教程

绘制左边Y轴

绘制主、次网格和主、次刻度的极坐标区域。

添加刮风数据,添加数据和颜色、图列大小映射关系。

颜色条绘制​​​​​​​

添加图列绘制​​​​​​​

绘图工具箱介绍

默认绘图​​​​​​​

刻度颜色设置​​​​​​​

刻度方向和长短设置,其中刻度方向有:'in'|'out'|'both'‍。​​​​​​​

网格设置:主、次网格的颜色、粗细、透明度设置。

背景颜色设置​​​​​​​

图列设置​​​​​​​

颜色条设置

WindRosePlot类函数

属性:

方法:


扫一扫关注公众号

效果图

粉丝给的图:

图片

复刻的图:

图片

其他样式效果:

图片

数据

数据包含:风向、刮风频率、最大风速、平均风速四个数据。

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];

数据长成这样的

图片

绘图教程

绘制左边Y轴

% 设置基础参数
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='风向频率(%)';

图片

绘制主、次网格和主、次刻度的极坐标区域。​​​​​​​

% 绘制主要的极坐标网格线
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);
end
majorTheta = 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);
end
minorTheta=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

图片

添加刮风数据,添加数据和颜色、图列大小映射关系。​​​​​​​

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);
    end
end
maxWind = 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

图片

颜色条绘制​​​​​​​

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);

图片

添加图列绘制​​​​​​​

% 定义半径和距离
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)));
end
axis equal;
xlim([-max(legR) max(legR)]);
ylim([legY(end)-legR(end) legY(1)+legR(1)]);
hold off;

图片

绘图工具箱介绍

默认绘图​​​​​​​

figure('name','默认绘图')
w=WindRosePlot(data);
w.plot();

图片

刻度颜色设置​​​​​​​

figure('name','设置刻度颜色')
w=WindRosePlot(data);
w.AxisColor=[0,0,1];
w.AxisLineWidth=2;
w.plot();

图片

刻度方向和长短设置,其中刻度方向有:'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();

图片

网格设置:主、次网格的颜色、粗细、透明度设置。

figure('name','主、次网格样式、颜色、粗细、透明度')
w=WindRosePlot(data);
w.RGrid='on';
w.RGridLineStyle='-.';
w.RGridColor=[1,0,0];
w.RGridAlpha=0.5;
w.RGridLineWidth=1.5;

w.ThetaGrid='on';
w.ThetaGridLineStyle='--';
w.ThetaGridColor=[0,1,0];
w.ThetaGridAlpha=0.5;
w.ThetaGridLineWidth=2;

w.MinorRGrid='on';
w.MinorRGridLineStyle='-';
w.MinorRGridColor=[1,1,0];

w.MinorThetaGrid='on';
w.MinorThetaGridLineStyle=':';
w.MinorThetaGridColor=[0,0,1];
w.plot();

图片

背景颜色设置​​​​​​​

figure('name','背景颜色')
w=WindRosePlot(data);
w.ColorMaps=hsv;
w.AxisBackgroundColor=[1,1,1]*0.10;
w.AxisFaceAlpha=0.1;
w.plot();

图片

图列设置​​​​​​​

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();

图片

颜色条设置

figure('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();
 

图片

图片

图片

图片

图片

图片

WindRosePlot类函数

收藏=学会

classdef 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 = obj.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 = obj.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
        function cMap=makeColorMap(obj,colorlist,num)
            color.Num= num;
            color.list=colorlist;
            for col=1:size(color.list,2)
                x=1:size(color.list,1);
                xi=linspace(1,size(color.list,1),color.Num);
                color.map(:,col)=interp1(x,color.list(:,col),xi);
            end
            cMap=color.map;
        end
    end
end

属性:

  • fig:存储图形的句柄。

  • WindDirections:风向数据。

  • WindFrequency:刮风频率。

  • MaxWindSpeed:最大风速数据。

  • AvgWindSpeed:平均风速数据。

  • RGrid,ThetaGrid,MinorRGrid,MinorThetaGrid:这些属性用于控制是否显示对应的网格线。

  • YLabel:Y轴标签。

  • 还有许多其他的属性,例如RGridLineStyle,RGridColor等,用于控制图形的样式和外观。

方法:

  1. 构造函数WindRosePlot:当创建WindRosePlot类的对象时,此构造函数将被调用。构造函数接收风玫瑰数据作为输入,并初始化类的属性。此外,还设置了默认的图形样式。

  2. plot方法:这个方法用于绘制风玫瑰图。它首先设置坐标轴和极坐标的属性。接下来,它会绘制主要和次要的R和Theta网格线。然后,它绘制刻度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/124143.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图的算法

拓扑排序算法 解析 要求&#xff1a;无环有向图 编译过程使用的是拓扑排序。A依赖BCD&#xff0c;在BCD三个文件编译完成才能引入A&#xff1b;B依赖ECD&#xff0c;在ECD三个文件编译完成才能引入B。拓扑排序排出整体的编译顺序E→CD→B→A 算法实现 找到整个图入度为0的点&…

4K壁纸下载器,多种风格壁纸,一键批量下载到本地,桌面壁纸,高清壁纸,壁纸下载

一个桌面壁纸爬虫工具&#xff0c;该工具可以从内置的多个壁纸网站爬取高清壁纸&#xff0c;并支持将壁纸一键下载到本地&#xff0c;真正实现了所见即所得&#xff0c;不必再费心费力的翻看多个网站。 文末附工具下载链接~ 一、软件简介 本次带来的工具由吾爱的一位大佬开发…

小白学爬虫:通过商品ID或商品链接封装接口获取淘宝商品销量数据接口|淘宝商品销量接口|淘宝月销量接口|淘宝总销量接口

淘宝商品销量接口是淘宝开放平台提供的一种API接口&#xff0c;通过该接口&#xff0c;商家可以获取到淘宝平台上的商品销量数据。使用淘宝商品销量接口的步骤如下&#xff1a; 1、在淘宝开放平台注册并创建应用&#xff0c;获取API Key和Secret Key等必要的信息。 2、根据淘宝…

终于有人说清楚了Cookie、Session、Token的区别。详解,面试题

前言&#xff1a; 众所周知&#xff0c;我们访问网页一般都是使用http协议&#xff0c;而http协议的每一次访问都是无状态的。 何为无状态&#xff1f;就是这一次请求和上一次请求是没有任何关系的、互不认识的、没有关联的。这种无状态的好处就是快速&#xff0c;坏处就是无法…

Unity热更新那些事

目录 热更新方案Unity程序的两种编译方式编译阶段执行阶段Mono方式IL2CPP方式两种方式打包以后的项目目录结构 其他 ILRuntime热更新ILRuntime使用注意ILRuntime的实现原理ILRuntime的性能优化建议ILRuntime的性能优化建议 HybridCLR热更新 参考链接 Unity热更新那些事 一小时极…

【算法与数据结构】216、LeetCode组合总和 III

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题可以直接利用77题的代码【算法与数据结构】77、LeetCode组合&#xff0c;稍作修改即可使用。   …

实验5-2——网络yum源的配置

网络yum源的配置 实验步骤&#xff1a; 1.在/etc/yum.repos.d中新建一个文件夹bak备份原来的东西,查看/etc/yum.repos.d/内容 cd /etc/yum.repos.d mkdir bak ls 2.把/etc/yum.repos.d中已有的repo文件都移入bak文件夹中并查看 mv *.repo bak ls 3. 下载安装weget以防万一本…

C语言 每日一题 11.9 day15

数组元素循环右移问题 一个数组A中存有N&#xff08; > 0&#xff09;个整数&#xff0c;在不允许使用另外数组的前提下&#xff0c;将每个整数循环向右移M&#xff08;≥0&#xff09;个位置&#xff0c;即将A中的数据由&#xff08;A0​A1⋯AN−1&#xff09;变换为&…

leetCode 206.反转链表 图解

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表 class Solution { public:ListNode* reverseList(ListNode* head) {ListNode* s NULL;ListNode* phead;while(p) {headhead->nex…

SQL第三次上机作业

1.查询与王利就读同一专业学生的借书证号和姓名 USE TSGL GO SELECT Lno,Rname FROM Reader WHERE Dept(SELECT DeptFROM ReaderWHERE Rname王利) and Rname ! 王利2.查询比希望出版社出版的所有图书价格都高的图书信息 SELECT * FROM Book WHERE Price>(SELECT MAX(Price…

MSQL系列(十四) Mysql实战-SQL语句 left join inner join On和Where语句的区别

Mysql实战-SQL语句On和Where语句的区别 前面我们讲解了Join的底层驱动表 选择原理&#xff0c;也知道了基本的内连接外连接两种SQL查询表连接方式 但是我们再查询多表的时候on和where语句到底有什么区别? where是过滤条件 ,不满足where的一定不会出现在结果中on是连接条件, …

SPASS-描述性分析

将身高移入变量 结果展示&#xff1a; 表中分析变量“身高”的个案数、所有个案中的极大值、极小值、均值、标准差及偏度和峰度

【React】04.MVC模式和MVVM模式

React是Web前端框架 1、目前市面上比较主流的前端框架 ReactAngular&#xff08;NG框架&#xff09;Vue 主流的思想&#xff1a; 不在直接去操作DOM&#xff0c;而是改为“数据驱动思想” 操作DOM思想&#xff1a; 操作DOM比较消耗性能[主要原因就是&#xff0c;可能会导…

【C/PTA——7.数组1】

C/PTA——7.数组1 7-1 计算最大值出现的次数1.题目要求2.代码实现 7-2 求一批整数中出现最多的个位数字1.题目要求2.代码实现 7-3 装箱问题1.题目要求2.代码实现 7-4 数组-值钱的微信号1.题目要求2.代码实现 7-5 数组-吹泡泡1.题目要求2.代码实现 7-6 数组-数学鬼才1.题目要求2…

JavaWeb Day05 前后端请求响应与分层解耦

目录 一、请求与响应 &#xff08;一&#xff09;请求的参数接收 ①数组参数 ②集合参数 ③日期参数 ④json参数 ⑤路径参数 总结 &#xff08;二&#xff09;响应 ①简单文本text ②数组 ③列表 ④同一响应数据格式 ⑤总结 二、三层架构与分层解耦 &#xff0…

前端特殊字符转码

前端特殊字符转码 建议 最好不要传名称&#xff0c;传ID 是在不行就用这个方法 name encodeURIComponent(name),

医院检验信息管理系统源码 医院LIS系统源码 云LIS源码 区域LIS源码

医院检验信息管理系统源码 医院LIS系统源码 云LIS源码 区域LIS源码 医院检验信息管理系统&#xff0c;利用计算机网络技术、数据存储技术、快速处理技术&#xff0c;对检验科进行全方位信息化管理&#xff0c;使检验科达到自动化运行&#xff0c;信息化管理和无纸化办公的目的…

【C++】万字详解IO流(输入输出流+文件流+字符串流)

文章目录 一、标准输入输出流1.1提取符>>&#xff08;赋值给&#xff09;与插入符<<&#xff08;输出到&#xff09;理解cin >> a理解ifstream&#xff08;读&#xff09; >> a例子 1.2get系列函数get与getline函数细小但又重要的区别 1.3获取状态信息…

矩阵键盘独立接口设计(Keil+Proteus)

前言 实验&#xff1a;通过4*4的矩阵键盘&#xff0c;按下某个按钮之后会在数码管上面显示对应的键号。&#xff08;0~F&#xff09; 基础操作参考这篇博客&#xff1a; LED数码管的静态显示与动态显示&#xff08;KeilProteus&#xff09;-CSDN博客https://blog.csdn.net/w…

13 # 手写 concat 方法

concat 的使用 concat() 方法用于合并两个或多个数组。此方法不会更改现有数组&#xff0c;而是返回一个新数组。如果省略了所有参数&#xff0c;则 concat 会返回调用此方法的现存数组的一个浅拷贝。 <script>var arr1 ["k", "a", "i"…