5
$\begingroup$

I have a set of scattered 3D points with coordinate (x,y,z) and an intensity associated with it.

I would like to do a smooth surface with the intensity being represented by the colour.

My points look like this

ListPointPlot3D[cup[[All, 1 ;; 3]]]

enter image description here

I can get the colour correctly by using (I found that on the net somewhere, cannot found it back ... sorry for not acknowledging the guy)

nf = Nearest[cup[[All, {1, 2, 3}]] -> Rescale[cup[[All, 4]]]]
colfun = ColorData["Rainbow"]@First@nf[{#1, #2, #3}] &

ListSurfacePlot3D[cup[[All, {1, 2, 3}]], MaxPlotPoints -> 30, 
 BoxRatios -> Automatic, ColorFunction -> colfun, 
 ColorFunctionScaling -> False, Mesh -> 5]

I tried playing around with the MaxPlotPoints but none give me satisfying results. The main issue is the fact that the top curve is not smooth although the data point are.

enter image description here

Finally I tried with ListPlot3D

ListPlot3D[cup[[All, {1, 2, 3}]], InterpolationOrder -> 15]

The problem there is that it incorrectly interpolate the extremum points, making a rectangle on the top whereas it should be curved.

enter image description here

Any idea how to proceed?

EDIT:

I also tried the idea of concave hull following this post Finding a Concave Hull

However this does not work either and give me

enter image description here

The data cup can be imported via cup = << "http://pastebin.com/raw/DRSCc4ir";

The full data (1.4Mb) can be imported via https://gist.githubusercontent.com/anonymous/327fed478fcf166c4403/raw/9f116770cf995f2232660061c202db7602b1836a/data.txt

Applying the solution provided by JasonB below I could merge my data to give:

enter image description here

$\endgroup$
  • 1
    $\begingroup$ Where's cup? ${}$ $\endgroup$ – J. M. is away Mar 13 '16 at 21:08
  • $\begingroup$ I've upload the raw data on speedyshare.com/sU5RR/cup.txt $\endgroup$ – sponce Mar 13 '16 at 21:15
  • 1
    $\begingroup$ For the interpolation, it's using the convex hull of the projection of your data onto the xy plane for the domain. What you want is something like what someone called the "concave hull" on this site (for a 3D volume). I don't know the answers there would help, but you could search and see. $\endgroup$ – Michael E2 Mar 13 '16 at 23:26
  • 1
    $\begingroup$ This is very hackish, but I wonder if you could simply "drop the ragged edges" from your data. For instance, you could generate a "cleaned" data set using cleanedcup = DeleteCases[cup, {x_, y_, z_, d_} /; z > 0.83];, and then using this cleanedcup wherever you originally had cup. For instance, the ListSurfacePlot3D approach would produce this image. $\endgroup$ – MarcoB Mar 14 '16 at 1:11
  • 1
    $\begingroup$ @sponce - I changed the upload location. Even though most every internet user knows not to click the "Download EXE" or "Fast Download" buttons, in this case it's easy to avoid that sketchiness. You can use pastebin for data that isn't too large, gist.github.com works for even larger files also. The added benefit is you can import the data straight into the notebook without even visiting the site. $\endgroup$ – Jason B. Mar 14 '16 at 8:55
5
$\begingroup$

The issue is that ListPlot3D interpolates in places where there is no density of points.

Show[Through[{ListPointPlot3D[#, PlotStyle -> PointSize[Large], 
      BoxRatios -> Automatic] &, ListPlot3D}[Most /@ cup]]]

enter image description here

It would be best if we could find a way to, as MichaelE2 pointed out, create a concave hull mesh from these points,

ListPlot[DeleteDuplicates@cup[[All, ;; 2]], AspectRatio -> Automatic]

enter image description here

and then restrict the plotting region to within those {x, y} points via RegionFunction. I can't find a simple way to generate the concave hull

Generating the concave hull is fairly simple using RunnyKine's function here.

cup = << "http://pastebin.com/raw/DRSCc4ir";

reg = alphaShapes2D[DeleteDuplicates@cup[[All, ;; 2]], .33]

enter image description here

and then the requested plot is made via,

nf = Nearest[cup[[All, {1, 2, 3}]] -> Rescale[cup[[All, 4]]]];
colfun = ColorData["Rainbow"]@First@nf[{#1, #2, #3}] &;
ListPlot3D[cup[[All, 1 ;; 3]],
  RegionFunction -> Function[{x, y, z}, RegionMember[reg, {x, y}]],
  ColorFunction -> colfun,
  ColorFunctionScaling -> False,
  MaxPlotPoints -> 100,
  BoxRatios -> Automatic,
  Mesh -> 5]

enter image description here

$\endgroup$
  • $\begingroup$ Thank you very much Jason ! It is indeed quite complicated. If you can come up with something simpler I would be happy. Indeed, I need to apply this to different shapes and I'm not sure this procedure would work in every cases. Anyhow, it works very well. Thanks again ! $\endgroup$ – sponce Mar 14 '16 at 14:41
  • 1
    $\begingroup$ @sponce - I've just edited it to be more straightforward. It should be applicable to different shapes, as long as you can define a region to plot into. If you can't get this method to work for another data set, post it and we might be able to help. $\endgroup$ – Jason B. Mar 14 '16 at 14:53
  • $\begingroup$ +1. I completely forgot I posted a 2D version of that alphaShapes code. Nice solution. $\endgroup$ – RunnyKine Mar 14 '16 at 18:56
  • 1
    $\begingroup$ @RunnyKine Thank you. You don't happen to have access to the original data from that post do you? I know the implementation I used isn't the conventional one and I wanted to see if it would remove the unwanted triangles in your final mesh in that post. Your code is about 100 times faster than mine, which is why I used it here and in another post about contour plots. $\endgroup$ – Jason B. Mar 14 '16 at 19:08
  • 1
    $\begingroup$ @sponce, can you upload the rest of the data so I can give it a shot? $\endgroup$ – Jason B. Mar 15 '16 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.