A 2D circle divided into 10 sectors in the 3D plot.

2 visualizaciones (últimos 30 días)
Dmitriy el 15 de Feb. de 2024
Comentada: Star Strider el 28 de Feb. de 2024
Hello, for the visualization of my research results, I would like to create a 3D chart with a circle split in sectors, similar to the one attached. But I need a circle divided into 10 sectors, and I would like to assign concentrations for each sector, for example like in the chart where circle is separated in squares. How can I do it?

Respuesta aceptada

Star Strider
Star Strider el 15 de Feb. de 2024
I am not exactly certain what you want.
One approach —
r = 7.5;
ac = linspace(0, 2*pi, 500).';
xc = r*cos(ac);
yc = r*sin(ac);
zc = zeros(size(ac));
as = linspace(0, 2*pi, 11).';
xs = r*cos(as);
ys = r*sin(as);
zs = zeros(size(as));
data = rand(50,3).*[2*pi r 150]; % 'Data': [Angle, Radius, Z-Value]
[X,Y,Z] = pol2cart(data(:,1), data(:,2), data(:,3)); % Convert To Cartesian For Plot
plot3(xc, yc, zc, '-k');
hold on
plot3([zs xs].', [zs ys].', [zs zs].', '-k');
scatter3(X, Y, Z, 25, Z, 'filled')
hold off
grid on
daspect([1 1 15]) % Sets Axes Aspect Ratio
plot3(xc, yc, zc, '-k');
hold on
plot3([zs xs].', [zs ys].', [zs zs].', '-k');
plot3(xc, yc, zc+150, '-k');
plot3([zs xs].', [zs ys].', [zs zs].'+150, '-k');
scatter3(X, Y, Z, 25, Z, 'filled')
hold off
grid on
daspect([1 1 15])
To assign them to specific segments in the plot, consider using stem3 as well, with 'Marker','none'. This will connect each data point to the ‘Z’ surface with a line, and can make the plot easier to understand.
  6 comentarios
Dmitriy el 28 de Feb. de 2024
I got it! Now I understand, have succesfully made charts for my work, thank You very much for your help!
Star Strider
Star Strider el 28 de Feb. de 2024
As always, my pleasure!

Iniciar sesión para comentar.

Más respuestas (1)

Adam Danz
Adam Danz el 16 de Feb. de 2024
Editada: Adam Danz el 16 de Feb. de 2024
Creating a polar heatmap within Cartesian coordinates
The basic idea is to create a polar grid centered under the data, plotted as a surface. The color in the surface is defined by the density of points that fall within each sector of the polar grid. To compute density, the 3D points are convered to 2D polar coordinates, ignoring z-coordinates. Then, each point is assigned to a section of the grid using logical conditions. Then the polar grid is converted back to Cartesian units and centered under the data.
Important caveat: The polar grid cells do not have the same area. This means that larger cells will contain more data points than smaller cells in a uniform distribution. This biases the interpretation of the colored regions. This could be corrected by normalizing the color values to the area of each segment in which case the colors would not indicate number of points but instead, number of points per unit of area.
Please also see a limitation to this visualization at the end of the answer.
Create data
data is an nx3 matrix of [x,y,z] coordinates.
rng default
data = pearsrnd(0,1,.6,4,500,3); % requires stats toolbox
% data = randn(200,3).*[1.2,1,1]+[2,-1,0]; % Alternative
Convert data to polar coordinates
% Shift data to be centered on (0,0) and convert to polar
center = mean(data(:,1:2)); % (x,y) center of the data
[xTheta, yRad] = cart2pol(data(:,1)-center(1),data(:,2)-center(2));
Create a polar grid
nThetaSectors determines the number of sections around the circle, starting and ending at -pi, pi.
nRadiiSectors determines the number of sections between the center and outer edge of the circle.
% Compute polar grid
nThetaSectors = 10; % parameter
thetaGrid = linspace(-pi,pi,nThetaSectors+1);
nRadiiSectors = 5; % parameter
maxRadius = max(yRad);
radiiGrid = linspace(0,maxRadius,nRadiiSectors+1);
Compute the density of data points within each polar grid cell
% Assign each point to a grid cell
% This only works when there is a border at -pi and pi
[radiusGroup, ~] = find((yRad(:)>radiiGrid(1:nRadiiSectors) & yRad(:)<=radiiGrid(2:end))');
[thetaGroup, ~] = find((xTheta(:)>thetaGrid(1:nThetaSectors) & xTheta(:)<=thetaGrid(2:end))');
% Create density grid
[gcounts,gvecs] = groupcounts([thetaGroup,radiusGroup]);
gidx = sub2ind([nThetaSectors, nRadiiSectors],gvecs{1},gvecs{2});
density = zeros(nThetaSectors, nRadiiSectors);
density(gidx) = gcounts;
Convert the polar grid to Cartesian coordinates
Here, we also shift the polar grid to the center of the data.
The grid is located under the data along the z-axis by finding the minimum z value and shifting downward by 5 % of the range of z-data.
% Create the polar grid in cartesian coordinates
[tg,rg] = ndgrid(thetaGrid,radiiGrid); % meshgrid requires transpose
[px, py] = pol2cart(tg,rg);
px = px + center(1);
py = py + center(2);
[minZ,maxZ] = bounds(data(:,3));
pFloor = minZ*(0.05*(maxZ-minZ));
pz = zeros(size(px)) + pFloor;
Plot the 3D scatter points
grid on
axis equal
Add the polar density surface
hold on
h = surf(px,py,pz,density,'FaceAlpha',.5,'EdgeAlpha',.3);
cb = colorbar();
cb.Label.String = 'Density';
axis vis3d
View from the bottom
Points are assigned to the segments assuming the segments are circular. The segments aren't plotted circularly, they are plotted as trapazoids. This means in some cases a point will appear outside of a segment when it was, in fact, counted as a member of that segment.
This is illustrated in the image below where a yellow segment indicates that it contains 1 data point. The yellow segement on the left counts the point just outside of the segment because it is within the circular zone (dotted line). This could lead to some confusing results.
One way to improve that is to compute density using inpolygon so belongingness is defined by the plotted trapezoidal segments.
Another way to improve this is to plot circular zones instead of trapezoidal zone.
Neither of these improvements would be quick and easy so I'll leave that to the next person.


Más información sobre Line Plots en Help Center y File Exchange.


Community Treasure Hunt

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

Start Hunting!

Translated by