4
$\begingroup$

I am looking for a way for variable partitioning of the data in the form of a "list of lists" for interpolating the imported data from excel. The data looks like:

data = {
  {{5., 9.53333, 0.057735}, {5., 19.3333, 0.057735}, {5.,29.2667, 0.057735},
   {5., 39.0667, 0.11547}, {5., 49., 0.}, {10., 11., 0.}, {10., 22.4, 4.35117*10^-15}, 
   {10., 33.6667, 0.057735}, {10., 45.1, 0.}, {10., 56.3333, 0.11547},
   {15., 12.4667, 0.057735}, {15., 25.2667, 0.057735}, {15., 38., 0.1}, 
   {15., 50.9333, 0.057735}, {15., 63.7667, 0.057735}, {20., 13.8333, 0.057735}, 
   {20., 28.1, 0.1}, {20., 42.3667, 0.057735}, {20., 56.5333, 0.057735}, 
   {20., 70.8667, 0.152753}}
       }

Now I want to interpolated this data using Interpolation function but the problem is that Interpolation needs the data in the form:

{{5., 9.53333}, 0.057735}, {{5., 19.3333}, 0.057735},...}

Without bothering about this form, if I try to Interpolate using command:

f = Interpolation[data[[1]], InterpolationOrder -> 2]

it interpolates but produces a warning as well:

 Interpolation::udeg: Interpolation on unstructured grids is currently only 
 supported for InterpolationOrder -> 1 or InterpolationOrder -> All. 
 Order will be reduced to 1.

I would have been happy if the 3D plot of f[x,y] would have been a bit better than this (I hate spikes in the plot):

3D plot when InterpolationOrder is 1

Overall, I think that the problem can be resolved by supplying "structured grids" to the Interpolation command and that's where I have got stuck. I need to arrange the data as it is required in the Interpolation command. I have also checked Mr Wizard's solution for [dynamic partitioning](Partitioning with varying partition size"list manipulation - Partitioning with varying partition size") but it dose not work (or I must say - I could not make it work) in this case. I have got a feeling that some modification in that will do the job but I do not know the workaround for that.
So the question is how to do that?

$\endgroup$

3 Answers 3

3
$\begingroup$

There are many ways to repartition the data. Here's one:

data2 = Flatten[data /. {x_, y_, z_} -> {{x, y}, z}, 1]

Then you can interpolate as before:

f = Interpolation[data2, InterpolationOrder -> 1]

Note that I have changed the order to 1 -- this is what the warning was telling you -- with data that is not on a regular grid, you cannot use order greater than 1. The jagged edges are then caused (not by the interpolation) but by the number of points used to plot. So changing the PlotPoints option makes it smoother:

Plot3D[f[x, y], {x, 5, 20}, {y, 9.5, 70}, PlotPoints -> 200]

enter image description here

As Mr Wizard points out, it might be safer to make sure that the replacement rule only applies to the numerical data, hence:

data2 = Flatten[data /. {x_?NumericQ, y_?NumericQ, z_?NumericQ} -> {{x, y}, z}, 1]

would be safer.

$\endgroup$
7
  • $\begingroup$ I wouldn't recommend this. You could get a false match with the pattern {x_, y_, z_} causing a nasty bug. You should make the replacement at a specific level or use _?NumericQ. Please see: (6543), (7688), (17497). $\endgroup$
    – Mr.Wizard
    Sep 25, 2013 at 12:56
  • $\begingroup$ Elegant and perfect. I never used Flatten command like that. Great !! Don't mind it but I can't +1 the reply. Sorry to You, Mr Wizard and Artes. Thanks a lot to all of you. Cheers !! :) $\endgroup$
    – incognito
    Sep 25, 2013 at 13:00
  • $\begingroup$ Thanks for the caution Mr Wizard. Checking out the possibility !! $\endgroup$
    – incognito
    Sep 25, 2013 at 13:03
  • $\begingroup$ Now you get my +1. $\endgroup$
    – Mr.Wizard
    Sep 25, 2013 at 13:14
  • 1
    $\begingroup$ @Om. Have you seen these?: (8458), (20334) $\endgroup$
    – Mr.Wizard
    Sep 26, 2013 at 12:26
3
$\begingroup$

I believe all you need is this:

newdata = {{#, #2}, #3} & @@@ data[[1]]
{{{5., 9.53333}, 0.057735}, {{5., 19.3333}, 0.057735}, {{5., 29.2667}, 0.057735}, . . .

If your data contains multiple sets you can use the long form of Apply and the appropriate levelspec, here {2}:

newdata = Apply[{{#, #2}, #3} &, data, {2}]

Reference:

$\endgroup$
2
  • $\begingroup$ I must say that was quick. May be it was easy for you. Thanks a ton. c :) $\endgroup$
    – incognito
    Sep 25, 2013 at 12:56
  • $\begingroup$ @Om. You're welcome. Yes, it was easy, but I spend way too much time playing with Mathematica syntax. :-) I think you will find a lot of power in Slot (#, #2, etc.) which is used in Function (short form &), and Apply. I use these functions all the time. Sometimes they are not optimal due to unpacking but they are convenient and concise, therefore often my first approach. $\endgroup$
    – Mr.Wizard
    Sep 25, 2013 at 13:02
2
$\begingroup$
d = {{#1, #2}, #3} & @@@ Flatten[data, 1]

or

d = {Most @ #, Last @ #}& /@ Flatten[data, 1]

e.g.

{Most@#, Last@#} & /@ Flatten[data, 1] // Short
{{{5., 9.53333}, 0.057735}, <<18>>, {{20., 70.8667}, 0.152753}}

Edit

Given data allow only for InterpolationOrder -> 1

f = Interpolation[ d, InterpolationOrder -> 1];

To visualize data we can make use of various options of Plot3D. To get a better resolution we rescaled z-axis using appropriate values of BoxRatios.

Plot3D[ f[x, y], {x, 5, 20}, {y, 14, 70}, PlotPoints -> 150,  MaxRecursion -> 4, 
        MeshFunctions -> {#3 &}, Mesh -> 30, ClippingStyle -> None, 
        ColorFunction -> "DeepSeaColors", BoxRatios -> {15, 60, 5}, 
        ViewPoint -> {-1, -3, 1}]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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