Polarplot draws unwanted lines to origin when envelope is not full circle (0–360°)
조회 수: 32 (최근 30일)
이전 댓글 표시
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'});
댓글 수: 0
채택된 답변
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
댓글 수: 2
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Polar Plots에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

