I have a list of points that may be used for linear interpolation using Interpolation and need to ensure that no two points have the same $x$ value, since, if they do, Interpolation reports errors:

enter image description here

Ideally I'd like to simply tweak such points just enough, that their control points don't shift visibly, but that they satisfy Interpolation (e.g. by adding a very small number to one of the offending points).

Alternatively, perhaps a different Mathematica interpolation function or different options for Interpolation avoid this error.

I've tried randomizing the points a bit, using various methods, but I get strange behavior, including briefly jagged plots (e.g. when changing settings for iorder) and eventual unresponsiveness of the control points (they just won't move).

 (*pts = MapAt[# + RandomReal[NormalDistribution[0, 10^-4]] &, 
   pts, -1];*)
 Plot[Interpolation[Prepend[pts, {0, 0}], InterpolationOrder -> iorder][x], {x, 0, 1}],
 {{pts, {{.2, .1}, {.4, .2}, {.6, .3}, {.8, .25}, {1, 0}}}, Locator},
 {{iorder, 3, "InterpolationOrder"}, Range[3], SetterBar}]

In context, I switch among even more curve fitting methods (e.g. Bezier, etc.), so dropping points is not an option, nor is moving them perceptibly, or skipping them.

  • $\begingroup$ Why not just add a tiny amount of random floating point error to all coordinates? $\endgroup$
    – whuber
    Nov 8, 2012 at 21:19
  • $\begingroup$ @whuber: I'm not sure how to do that, if I precede the plot with something like pts = {RandomReal[{#[[1]] - .0001, #[[1]] + .0001}], #[[2]]} & /@ pts;, I get a wobbly plot. $\endgroup$
    – orome
    Nov 8, 2012 at 21:36
  • $\begingroup$ what about DeleteDuplicates? $\endgroup$
    – chris
    Nov 8, 2012 at 21:40
  • $\begingroup$ @chris: No dropping, skipping or (perceptibly) moving of points. All the control points need to pretty much seem to stay where there are. They can "stick" of shift a tiny amount if that's the only way, but removing them is definitely out. $\endgroup$
    – orome
    Nov 8, 2012 at 21:48
  • 1
    $\begingroup$ I don't know what the structure of points is intended to be, so I'll give you an inefficient generic solution to jitter all the coordinates: MapAt[# + RandomReal[NormalDistribution[0, 10^-4]] &, points, -1]. Use a uniform distribution to limit the amount of jittering if you like and change the 10^-4 to suit your tastes. Generalizations of this approach will jitter only the x-coordinates. The idea here is to avoid looking for duplicates altogether. And if you're willing to change some coordinates, arguably it's best to change them all in the same fashion. $\endgroup$
    – whuber
    Nov 8, 2012 at 21:51

2 Answers 2


Assuming your points are in order, then you could just use a rule:

rule = {before___, {x_, y1_}, {x_, y2_}, after___} -> 
       {before, {x, y1}, {x + tweak, y2}, after}

Then apply with repeated replacement:

pts //. rule
  • $\begingroup$ That seems to do the trick! $\endgroup$
    – orome
    Nov 8, 2012 at 22:13

It seems that interpolation in two dimensions is desired. To do so, interpolate the x- and y-coordinates separately and plot the curve parametrically:

 Module[{f = Interpolation[#, InterpolationOrder -> iorder] & /@ 
             Transpose[Prepend[pts, {0, 0}]]},
  ParametricPlot[Through[f[x]], {x, 1, Length[pts]+1}, PlotRange -> {Full, Full}]],
 {{pts, {{.2, .1}, {.4, .2}, {.6, .3}, {.8, .25}, {1, 0}}}, Locator},
 {{iorder, 3, "InterpolationOrder"}, Range[3]}]


Now it does not matter that some of the x-coordinates may have been duplicated.

  • 1
    $\begingroup$ "...interpolate the $x$- and $y$-coordinates separately and plot the curve parametrically." - in that regard, one might consider using something like centripetal parametrization for the purpose... $\endgroup$ Nov 9, 2012 at 16:21
  • $\begingroup$ @J.M. Thanks for that reference. $\endgroup$
    – whuber
    Nov 9, 2012 at 16:24

Your Answer

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

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