I'd like to plot grouped data in a scatter plot with marginal histograms using Matlab. There is a function to do just that: scatterhist.
However, I'm dealing with some visualization issues: I have a large number of data points and many points are printed one over another (changing marker type and marker size doesn't help).
Therefore, I'd prefer to substitute individual points from each group with their convex hull; i.e., if I have 5 groups, the plot would show 5 convex hulls and keep marginal histograms generated from the original data points. Do you know if there is an easy way to do this or if this has already been implemented?
In the end, I came up with the following:
Use scatterhist to create the scatter plot with marginal histograms.
hold on
Use convhull to get the convex hull for each group of points.
Use fill to draw the convex hull.
Related
When you want to plot scatter points with fixed alpha value in Matlab, you may the patch function, like advised in this SO question. But when you want to plot a high number of individual points, you should use the plot function, as advised in this SO question.
Is it still possible to plot a high number of scatter points with fixed alpha value in Matlab ?
I want to visualize 4 vectors of scattered data with a surface plot. 3 vectors should be the coordinates. In addition the 4th vector should represent a surface color.
My first approach was to plot this data (xk,yk,zk,ck) using
scatHand = scatter3(xk,yk,zk,'*');
set(scatHand, 'CData', ck);
caxis([min(ck), max(ck)])
As a result I get scattered points of different color. As these points lie on the surface of a hemisphere it ist possible to get colored faces instead of just points. I replace the scattered points by a surface using griddata to first build an approximation
xk2=sort(unique(xk));
yk2=sort(unique(yk));
[xxk, yyk]=meshgrid(xk2, yk2);
zzk=griddata(xk,yk,zk,xxk,yyk,'cubic');
cck=griddata(xk,yk,clr,xxk,yyk,'cubic');
surf(xxk,yyk,zzk,cck);
shading flat;
This is already nearly what I want except that the bottom of the hemisphere is ragged. Of course if I increase the interpolation point numbers it gets better but than the handling of the plot gets also slow. So I wonder if there is an easy way to force the interpolation function to do a clear break. In addition it seems that the ragged border is because the value of zzk gets 'NaN' outside the circle the hemisphere shares with the z=0-plane.
The red points at the top are the first several entries of the original scattered data.
You can set the ZLim option to slice the plotted values within a certain range.
set(gca, 'Zlim', [min_value max_value])
I have a formula that depends on theta and phi (spherical coordinates 0<=theta<=2*pi and 0<=phi<=pi). By inserting each engle, I obtained a quantity. Now I have a set of data for different angles and I need to plot the surface. My data is a 180*360 matrix, so I am not sure if I can use SURF or MESH or PLOT3. The figure should be a surface that include all data and the axes should be in terms of the quantity, not the quantity versus the angles. How can I plot such a surface?
I see no reason why you cannot use mesh or surf to plot such data. Another option I tend to use is that of density plots. You basically display the dependent variable (quantity) as an image and include the independent variables (angles) along the axis, much like you would with the aforementioned 3D plotting functions. This can be done with imagesc.
Typically you would want your axes to be the dependent variables. Could you elaborate more on this point?
If I understand you correctly you have calculated a function f(theta,phi) and now you want to plot the surface containing all the points with the polar coordinated (r,theta,phi) where r=f(theta,phi).
If this is what you want to do, the 2D version of such a plot is included in MATLAB under the name polar. Unfortunately, as you pointed out, polar3 on MatlabCentral is not the generalization you are looking for.
I have been able to plot a sphere with the following code, using constant r=1. You can give it a try with your function:
phi1=0:1/(3*pi):pi; %# this would be your 180 points
theta1=-pi:1/(3*pi):pi; % your 360 points
r=ones(numel(theta1),numel(phi1));
[phi,theta]=meshgrid(phi1,theta1);
x=r.*sin(theta).*cos(phi);
y=r.*sin(theta).*sin(phi);
z=r.*cos(theta);
tri=delaunay(x(:),y(:),z(:));
trisurf(tri,x,y,z);
From my tests it seems that delaunay also includes a lot of triangles which go through the volume of my sphere, so it seems this is not optimal. So maybe you can have a look at fill3 and construct the triangles it draws itself: as a first approximation, you could have the points [x(n,m) x(n+1,m) x(n,m+1)] combined into one triangle, and [x(n+1,m) x(n+1,m+1) x(n+1,m+1)] into another...?
I have a large (~60,000) set of triplet data points representing x,y, and z coordinates, which are scattered throughout a Cartesian volume.
I'm looking for a way to use Matlab to visualize the non-convex shape/volume described by the maximum extent of the points.
I can of course visualize the individual points using scatter3, but given the large number of points the details of the shape are obscured by the noise of the dots.
As an analogy, imagine that you filled a hour glass with spheres of random sizes such as BBs, ping pong balls, and kix and then were given the coordinates of the center of each of each object. How would you take those coordinates and visualize the shape of the hour glass containing them?
My example uses different sized objects because the spacing between data points is non-uniform and effectively random; it uses an hourglass because the shape is non-convex.
If your surface enclosing the points can be described as a convex polyhedron (i.e. like the surface of a cube or a dodecahedron, without concave pits or jagged pointy parts), then I would start by creating a 3-D Delaunay triangulation of the points. This will fill the volume around the points with a series of tetrahedral elements with the points as their vertices, and you can then find the set of triangular faces that form the outer shell of the volume using the convexHull method of the DelaunayTri class.
Here's an example that generates 200 random points uniformly distributed within the unit cube, creates a tetrahedral mesh for these points, then finds the 3-D convex hull for the volume:
interiorPoints = rand(200,3); %# Generate 200 3-D points
DT = DelaunayTri(interiorPoints); %# Create the tetrahedral mesh
hullFacets = convexHull(DT); %# Find the facets of the convex hull
%# Plot the scattered points:
subplot(2,2,1);
scatter3(interiorPoints(:,1),interiorPoints(:,2),interiorPoints(:,3),'.');
axis equal;
title('Interior points');
%# Plot the tetrahedral mesh:
subplot(2,2,2);
tetramesh(DT);
axis equal;
title('Tetrahedral mesh');
%# Plot the 3-D convex hull:
subplot(2,2,3);
trisurf(hullFacets,DT.X(:,1),DT.X(:,2),DT.X(:,3),'FaceColor','c')
axis equal;
title('Convex hull');
You could treat your data as a sample from a three-dimensional probability density, and estimate that density on a grid, e.g. via a 3d histogram, or better a 3d kernel density estimator. Then apply a threshold and extract the surface using isosurface.
Unfortunately, hist3 included in the Statistics Toolbox is (despite its name) just a 2d histogram, and ksdensity works only with 1d data, so you would have to implement 3d versions yourself.
I have a 2D scatter plot in MATLAB. Is it possible to interpolate the scatter plot to create an area plot?
If you're simply trying to draw one large filled polygon around your entire set of scattered points, you can use the function CONVHULL to find the convex hull containing your points and the function PATCH to display the convex hull:
x = rand(1,20); %# 20 random x values
y = rand(1,20); %# 20 random y values
hullPoints = convhull(x,y); %# Find the points defining the convex hull
patch(x(hullPoints),y(hullPoints),'r'); %# Plot the convex hull in red
hold on; %# Add to the existing plot
scatter(x,y); %# Plot your scattered points (for comparison)
And here's the resulting figure:
Scatter is generally used to represent data where you can't use a line graph, i.e., where each x might have many different y values, so you can't convert directly to an area graph--it would be meaningless. If your data actually is representable as a line graph, then pass it to area directly.
So I'm not quite sure what you want, but here are some possibilities:
You could create a Voronoi diagram based on your points. This will show a region near your points showing which points are closer to a specific point: voronoi(x,y), or see the help.
You could bucket or quantize your data somehow, making it fit into a grid, and then plot the grid. This could also be considered a histogram, so read up on that.
You could just use larger scatter markers (scatter(x,y,scale) where scale is the same dimensions as x and y).