Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question

3 Answers 3

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.

share|improve this answer
    
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). –  Mr.Wizard Sep 25 '13 at 12:56
    
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 !! :) –  Om. Sep 25 '13 at 13:00
    
Thanks for the caution Mr Wizard. Checking out the possibility !! –  Om. Sep 25 '13 at 13:03
    
Now you get my +1. –  Mr.Wizard Sep 25 '13 at 13:14
1  
@Om. Have you seen these?: (8458), (20334) –  Mr.Wizard Sep 26 '13 at 12:26

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:

share|improve this answer
    
I must say that was quick. May be it was easy for you. Thanks a ton. c :) –  Om. Sep 25 '13 at 12:56
    
@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. –  Mr.Wizard Sep 25 '13 at 13:02
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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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