Polarplot draws unwanted lines to origin when envelope is not full circle (0–360°)

조회 수: 32 (최근 30일)
Bea
Bea 2025년 10월 14일 8:47
댓글: Mathieu NOE 2025년 10월 14일 14:59
Hi everyone,
I'm creating a polar plot that visualizes measured values (like power) depending on wind direction and wind speed. I also overlay an envelope curve to define the acceptable range. When this envelope covers the full 360°, everything works as expected – I get a clean, closed curve.
However, when the envelope data only spans a partial angular range (e.g. 0° to 180°), MATLAB draws unwanted radial lines from the origin (0,0) to each point in the polarplot. These lines distort the visualization and are not part of the envelope.
I want the envelope to be a clean, curved line only between the actual data points. It should look like this:
I'm using the following helper function to prepare the data for polarplot:
What I tried so far:
[theta_rad, r_final] = prepareClosedPolarLine(envelope1.WindDirectionDeg, envelope1.WindSpeed);
function [theta_rad_final, r_final] = prepareClosedPolarLine(windDir_deg, windSpeed)
%PREPARECLOSEDPOLARLINE Creates a closed line in polar plot.
% It connects wind direction and wind speed data into a clean line,
% even when the angle range is incomplete (e.g., only 0°–180%).
% Ensure column vectors
theta_deg = windDir_deg(:);
r = windSpeed(:);
% Filter valid values
validIdx = ~isnan(theta_deg) & ~isnan(r);
theta_deg = theta_deg(validIdx);
r = r(validIdx);
% Normalize angles to [0, 360)
theta_deg = mod(theta_deg, 360);
% Sort by angle
[theta_deg_sorted, sortIdx] = sort(theta_deg);
r_sorted = r(sortIdx);
% Close the loop by adding first point at the end
theta_deg_closed = [theta_deg_sorted; theta_deg_sorted(1)];
r_closed = [r_sorted; r_sorted(1)];
% Convert to radians for polarplot
theta_rad_final = deg2rad(theta_deg_closed);
r_final = r_closed;
end
envelopeName = "Test";
polarplot(theta_rad, r_final, 'k-', 'MarkerSize', 8, 'LineWidth', 1, 'DisplayName', envelopeName);
Unfortunately neither GPT-4 nor Qwen3-Coder had any good ideas for this. The problem seems to be caused by the envelope not going through all for sections of the plot. Thanks so much for helping:
Data:
% It works for this type of data, covering all of the 360° range
envelope1 = table( ...
[40; 40; 40; 40; 35; 35; 25; 25; 10; 10; 10; 10; 10; 10; 10; 5; 5; 5; 5; 5; ...
5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 10; 20; 20; 20; 25; ...
25; 30; 30; 55; 55; 60; 60], ...
[0; 10; 10; 15; 15; 20; 20; 30; 30; 40; 50; 60; 70; 80; 90; 90; 100; 110; ...
120; 130; 140; 150; 160; 170; 180; 190; 200; 210; 220; 230; 240; 250; ...
260; 270; 280; 280; 290; 300; 300; 310; 320; 320; 330; 330; 335; 335; ...
340; 340; 350], ...
'VariableNames', {'WindSpeed', 'WindDirectionDeg'});
% but not for this
envelope2 = table( ...
[60; 60; 40; 40; 25; 25; 20; 20; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; ...
10; 10; 15; 20; 20; 20; 25; 25; 30; 30; 50; 50; 55; 55; 55], ...
[0; 10; 10; 15; 15; 20; 20; 30; 30; 20; 10; 0; 350; 340; 330; 320; ...
310; 300; 290; 280; 280; 300; 300; 300; 310; 320; 320; 330; 330; ...
335; 335; 340; 340; 350; 0], ...
'VariableNames', {'WindSpeed', 'WindDirectionDeg'});

채택된 답변

Mathieu NOE
Mathieu NOE 2025년 10월 14일 12:55
hello
seems to me that your data shoud NOT be sorted by angle. Of course this means you have to have the data ordered so that it indeed follows a nicely closed curve (if I randomise the data this will not be anymore true)
so your code without angle sorting works for both datas :
% It works for this type of data, covering all of the 360° range
envelope1 = table( ...
[40; 40; 40; 40; 35; 35; 25; 25; 10; 10; 10; 10; 10; 10; 10; 5; 5; 5; 5; 5; ...
5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 10; 20; 20; 20; 25; ...
25; 30; 30; 55; 55; 60; 60], ...
[0; 10; 10; 15; 15; 20; 20; 30; 30; 40; 50; 60; 70; 80; 90; 90; 100; 110; ...
120; 130; 140; 150; 160; 170; 180; 190; 200; 210; 220; 230; 240; 250; ...
260; 270; 280; 280; 290; 300; 300; 310; 320; 320; 330; 330; 335; 335; ...
340; 340; 350], ...
'VariableNames', {'WindSpeed', 'WindDirectionDeg'});
envelopeName = "Test";
[theta_rad, r_final] = prepareClosedPolarLine(envelope1.WindDirectionDeg, envelope1.WindSpeed);
polarplot(theta_rad, r_final, 'k-', 'MarkerSize', 8, 'LineWidth', 1, 'DisplayName', envelopeName);
% but not for this
envelope2 = table( ...
[60; 60; 40; 40; 25; 25; 20; 20; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; 5; ...
10; 10; 15; 20; 20; 20; 25; 25; 30; 30; 50; 50; 55; 55; 55], ...
[0; 10; 10; 15; 15; 20; 20; 30; 30; 20; 10; 0; 350; 340; 330; 320; ...
310; 300; 290; 280; 280; 300; 300; 300; 310; 320; 320; 330; 330; ...
335; 335; 340; 340; 350; 0], ...
'VariableNames', {'WindSpeed', 'WindDirectionDeg'});
envelopeName = "Test";
[theta_rad, r_final] = prepareClosedPolarLine(envelope2.WindDirectionDeg, envelope2.WindSpeed);
polarplot(theta_rad, r_final, 'k-', 'MarkerSize', 8, 'LineWidth', 1, 'DisplayName', envelopeName);
function [theta_rad_final, r_final] = prepareClosedPolarLine(windDir_deg, windSpeed)
%PREPARECLOSEDPOLARLINE Creates a closed line in polar plot.
% It connects wind direction and wind speed data into a clean line,
% even when the angle range is incomplete (e.g., only 0°–180%).
% Ensure column vectors
theta_deg = windDir_deg(:);
r = windSpeed(:);
% Filter valid values
validIdx = ~isnan(theta_deg) & ~isnan(r);
theta_deg = theta_deg(validIdx);
r = r(validIdx);
% Normalize angles to [0, 360)
theta_deg = mod(theta_deg, 360);
% % Sort by angle
% [theta_deg, sortIdx] = sort(theta_deg);
% r = r(sortIdx);
% Close the loop by adding first point at the end
theta_deg_closed = [theta_deg; theta_deg(1)];
r_closed = [r; r(1)];
%Convert to radians for polarplot
theta_rad_final = deg2rad(theta_deg_closed);
r_final = r_closed;
end

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Polar Plots에 대해 자세히 알아보기

제품


릴리스

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by