fill area between two polar curves

Hello , i have these two formulas, i would like to fill the area between these two curves is there a way to do it with patch command?
Thanks
phi=0.87*sin((log(r)*pi)/(log(tau)));
phi_shifted_45=0.87*sin((log(r)*pi)/(log(tau)))+0.78;

 Accepted Answer

The patch function will not work with polar axes. It throws this error:
Error using patch
While setting property 'Parent' of class 'Patch':
Patch cannot be a child of PolarAxes.
Oh, well...
The best I can do with this is to use pol2cart:
tau = 0.5;
r = linspace(eps, 1.5, 500);
phi = 0.87*sin((log(r)*pi)/(log(tau)));
phi_shifted_45 = 0.87*sin((log(r)*pi)/(log(tau)))+0.78;
[x1,y1] = pol2cart(phi, r);
[x2,y2] = pol2cart(phi_shifted_45, r);
figure(1)
patch([x1 fliplr(x2)], [y1 fliplr(y2)], 'g')
axis equal
Note to MathWorks: Can we have a patch for polar coordinate systems when you have time to implement it?

4 Comments

fima v
fima v on 17 Feb 2017
Edited: Walter Roberson on 14 Aug 2025
i have tried to continue one of the curves to make a round ending is there a way to smooth the form by continuing one the forms?
Thanks
My pleasure.
Yes!
I decided to go ‘all in’ on this while I was at it, and ‘rounded’ straight line (it took me just a bit to figure that out), then added the circumference and all the other grid lines.
The Code
tau = 0.5;
rlim = 1.5;
r = linspace(eps, rlim, 500);
phi = 0.87*sin((log(r)*pi)/(log(tau)));
phi_shifted_45 = 0.87*sin((log(r)*pi)/(log(tau)))+0.78;
[x1,y1] = pol2cart(phi, r);
[x2,y2] = pol2cart(phi_shifted_45, r);
rc = 1.5*ones(1, 50); % ‘Round’ The Connecting Line
phic = linspace(phi(end), phi_shifted_45(end), 50);
[xc,yc] = pol2cart(phic, rc);
cfull = linspace(0, 2*pi, 1000); % Full Circle Circumference
ccf = @(rd,th) [rd*cos(th); rd*sin(th)]; % Function
cc15 = ccf(rlim,cfull); % R = 1.5
cc10 = ccf(1,cfull); % R = 1.0
cc05 = ccf(0.5,cfull); % R = 0.5
rrv = [0:30:360]*pi/180; % Calcualte Radials
[rd00x, rd00y] = pol2cart(rrv, zeros(size(rrv)));
[rd15x, rd15y] = pol2cart(rrv, rlim*ones(size(rrv)));
rdx = [rd00x; rd15x];
rdy = [rd00y; rd15y];
figure(1)
patch([x1 xc fliplr(x2)], [y1 yc fliplr(y2)], 'g') % Plot Functions
hold on
plot(cc15(1,:), cc15(2,:), 'k') % Plot Full Circumference
plot(cc10(1,:), cc10(2,:), 'k')
plot(cc05(1,:), cc05(2,:), 'k')
plot(rdx, rdy, 'k') % Plot Radials
hold off
axis([-1 1 -1 1]*1.8)
axis square
set(gca, 'XColor','none', 'YColor','none')
The Plot
I leave the angle and radius labels to you. Use the text function for them, and note the name-value pair arguments that will allow you to line them up the way you want them where you want them.
Not sure if this is really a solution, but I find it weird that the old function "polar" that was in much earlier releases of MATLAB can handle patches fine. So, if you want to plot a patch, you can just use "polar" instead of "polarplot".
In the later releases, "polar" is not recommend for use and MATLAB suggests users use polarplot instead. Frustrating when updates actually cause a loss in functionality rather than a gain...
@Darcy Cordell — Note that my code uses strictly Cartesian coordinates (the pol2cart calls), and draws the polar axes grid separately. I have not attempted to do somoething similar with either polar or polarplot. (That may not even have been an option in R2017a.)

Sign in to comment.

More Answers (3)

@Star Strider asked, "Note to MathWorks: Can we have a patch for polar coordinate systems when you have time to implement it?"
⭐Starting in R2025a, polar axes accept patch objects
A patch can be used to fill beween two lines by stitching the endpoints of the lines together like this (credit to OP and Star Strider for the demo data).
tau = 0.5;
r = linspace(eps, 1.5, 500);
phi = 0.87*sin((log(r)*pi)/(log(tau)));
phi2 = 0.87*sin((log(r)*pi)/(log(tau)))+0.78;
figure()
pax = polaraxes();
patch(pax, [phi, flip(phi2)], [r, flip(r)], 'cyan', FaceAlpha = 0.4)
The patch vertices in polar axes are connected using Euclidean lines which is why there is a straight line segment on the outer edge. Converting that to a curved connection takes a bit more work. You have to generate the curved cooridinates and insert them into the vector of patch coordinates.
It's generally a bad idea to interpolate polar data due to the potential of angular data crossing the 0|360 border. That wouldn't be a problem for this example but I'll provide a more general solution that interpolates in Cartesian coordinates.
% [a b; c d] theta end points connect from a->b and c->d
endpoints = [phi(end), phi2(end);
phi2(1), phi(1)];
xEndpoints = cos(endpoints);
yEndpoints = sin(endpoints);
n = 10; % number of points in connection line
x = diff(xEndpoints,[],2)*(0:1/(n-1):1)+xEndpoints(:,1);
y = diff(yEndpoints,[],2)*(0:1/(n-1):1)+yEndpoints(:,1);
thConnector = atan2(y,x);
rConnector = r([end,1])'*ones(1,n);
thTotal = [phi, thConnector(1,:), flip(phi2), thConnector(2,:)];
rTotal = [r, rConnector(1,:), flip(r), rConnector(2,:)];
figure()
pax = polaraxes();
patch(pax, thTotal, rTotal, 'cyan', FaceAlpha = 0.4)

2 Comments

Interesting! I wasn't aware of that upgrade.
I'll keep that in mind.
maybe the unrwap function would help when crossing the 0|360 border

Sign in to comment.

I answered a similar question earilier today (https://www.mathworks.com/matlabcentral/answers/340760-how-to-fill-the-area-between-two-curves-on-a-polar-plot#answer_818143), but this one requires a more general solution than the one given there. The idea is the same, to overlay a transparent cartesian axes over the polar axes. This function (polarfill), however, recognizes that you may want to fill between different angles, not just different radii:
tau = 0.5;
r = linspace(eps, 1.5, 500);
phi = @(r)0.87*sin((log(r)*pi)/(log(tau))); %lambda function
phi_shifted_45 = @(r)0.87*sin((log(r)*pi)/(log(tau)))+0.78; %lambda function
f = figure();
polarplot(phi(r),r,'k','LineWidth',2); hold on; ax_pol = gca;
polarplot(phi_shifted_45(r),r,'r','LineWidth',2)
polarfill(ax_pol,phi(r),phi_shifted_45(r),r,r,'b',0.5)
%% Filling the extra gap
r_upper = 1.5; % The upper radius is constant
theta_range = linspace(phi(r_upper),phi_shifted_45(r_upper)); % The range of theta for the area
% Determining the polar equation for the lower radius as a function of theta
[x1,y1] = pol2cart(theta_range(1),r_upper); % Polar -> Cartesian
[x2,y2] = pol2cart(theta_range(end),r_upper); % Polar -> Cartesian
m = (y2-y1)/(x2-x1); % Slope of a line
b = y1-m*x1; % Intercept of a line
r_lower = - b ./ (m*cos(theta_range)-sin(theta_range)); % polar equation of a straight line
% Second call to Polar Fill
polarfill(ax_pol,theta_range,theta_range,r_lower,r_upper,'b',0.5)
function polarfill(ax_polar,thetal,thetah,rlow,rhigh,color,alpha)
ax_cart = axes();
ax_cart.Position = ax_polar.Position;
[xl,yl] = pol2cart(thetal,rlow);
[xh,yh] = pol2cart(fliplr(thetah),fliplr(rhigh));
fill([xl,xh],[yl,yh],color,'FaceAlpha',alpha,'EdgeAlpha',0);
xlim(ax_cart,[-max(get(ax_polar,'RLim')),max(get(ax_polar,'RLim'))]);
ylim(ax_cart,[-max(get(ax_polar,'RLim')),max(get(ax_polar,'RLim'))]);
axis square; set(ax_cart,'visible','off');
end

6 Comments

This is very nice, thank you! However, it does not work if I change rlim before calling the polarfill function
NOTE — This does not fill all the way to the circumference (between about 310° and 395°). That required a separate step in my code.
@Rosa, that's correct. We ran into the same issue last night generating a figure for a publication. The solution is to shift everything so all the data is positive and the lower limit on RLim is 0. Then use rticks() and rticklabels() to hide the shift! Hope that helps!
@Star Strider I've updated the answer to fill the extra gap.
how would this function be implemented in appdesigner? I tried to use polarfill, but when I run the app, a new figure pops for me with random stuff in it instead of coloring the polaraxes I created in the UIFigure. This is the code i run in the appdesigner
Pax = polaraxes(app.UIFigure);
Pax.Units = 'pixels';
Pax.Position = [478 14 430 297];
theta1 = (22.5*pi/180):0.01*pi:(67.5*pi/180);
rho1 = 2*ones(size(theta1));
polarplot(theta1, rho1);
Rlow = 0;
Rhigh = 2;
ax_cart = axes();
ax_cart.Position = Pax.Position;
[XL, YL] = pol2cart(theta1, Rlow);
[XH, YH] = pol2cart(fliplr(theta1), fliplr(Rhigh));
fill([XL,XH],[YL,YH],'blue','FaceAlpha',0.4,'EdgeAlpha',0);
xlim(ax_cart,[-max(get(Pax,'RLim')),max(get(Pax,'RLim'))]);
ylim(ax_cart,[-max(get(Pax,'RLim')),max(get(Pax,'RLim'))]);
axis square; set(ax_cart,'visible','off');
Pax.ThetaZeroLocation = 'top';
Pax.ThetaLim = [-180 180];
Pax.RLim = [0 1];
Pax.ThetaTick = -180:45:180;
I run similar code in a .m file and I get this
Pax = polaraxes;
theta = (22.5*pi/180):0.01*pi:(67.5*pi/180);
rho = 2*ones(size(theta));
polarplot(theta, rho);
rlim([0 1]);
polarfill(Pax, theta, 0, 1,'green', 0.3);
function polarfill(ax_polar,theta,rlow,rhigh,color,alpha)
ax_cart = axes();
ax_polar.ThetaLim = [-180 180];
ax_polar.ThetaZeroLocation = 'top';
ax_polar.ThetaTick = -180:45:180;
ax_cart.Position = ax_polar.Position;
[xl,yl] = pol2cart(theta,rlow);
[xh,yh] = pol2cart(fliplr(theta),fliplr(rhigh));
fill([xl,xh],[yl,yh],color,'FaceAlpha',alpha,'EdgeAlpha',0);
xlim(ax_cart,[-max(get(ax_polar,'RLim')),max(get(ax_polar,'RLim'))]);
ylim(ax_cart,[-max(get(ax_polar,'RLim')),max(get(ax_polar,'RLim'))]);
axis square; set(ax_cart,'visible','off');
end
could you help me?
Pax = polaraxes;
theta = (22.5*pi/180):0.01*pi:(67.5*pi/180);
rho = 2*ones(size(theta));
polarplot(theta, rho);
rlim([0 1]);
polarfill(Pax, theta, 0, 1,'green', 0.3);
function polarfill(ax_polar,theta,rlow,rhigh,color,alpha)
ax_cart = axes();
ax_polar.ThetaLim = [-180 180];
ax_polar.ThetaZeroLocation = 'top';
ax_polar.ThetaTick = -180:45:180;
ax_cart.Position = ax_polar.Position;
[xl,yl] = pol2cart(theta,rlow);
[xh,yh] = pol2cart(fliplr(theta),fliplr(rhigh));
fill([xl,xh],[yl,yh],color,'FaceAlpha',alpha,'EdgeAlpha',0);
xlim(ax_cart,[-max(get(ax_polar,'RLim')),max(get(ax_polar,'RLim'))]);
ylim(ax_cart,[-max(get(ax_polar,'RLim')),max(get(ax_polar,'RLim'))]);
axis square; set(ax_cart,'visible','off');
end
I had some issues with this, but I changed added the unwrap function to the angle data, and that fixed everything (no fliplr needed).
[xl,yl] = pol2cart(unwrap(theta),rlow);
[xh,yh] = pol2cart(unwrap(theta),rhigh)

Sign in to comment.

I you need to do a subplot with this fill the polarfill axes are not aligned and it makes for a very messy fill, this can be solved easily with the 'align' function of subplot
subplot(rows, cols, i, 'align')

Categories

Asked:

on 17 Feb 2017

Edited:

on 30 Sep 2025

Community Treasure Hunt

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

Start Hunting!