0
$\begingroup$

Supposing we have the following list (very small, can be copied into a notebook directly)

{
{1.25, 0},
{1.3, 0.125},
{1.4, 0.175},
{1.5, 0.225},
{1.6, 0.275}, {1.7, 0.275},
{1.8, 0.325},
{1.9, 0.375}, {2., 0.375}, {2.1, 0.375},
{2.2, 0.425}, {2.3, 0.425},
{2.4, 0.475}, {2.5, 0.475}, {2.6, 0.475}, {2.7, 0.475},
{2.8, 0.525}, {2.9, 0.525}, {3., 0.525},
{3.1, 0.575}, {3.2, 0.575}, {3.3, 0.575}, {3.4, 0.575}, {3.5, 0.575},
{3.6, 0.625}, {3.7, 0.625}, {3.8, 0.625}, {3.9, 0.625}, {4., 0.625},
{4.1, 0.675}, {4.2, 0.675}, {4.3, 0.675}, {4.4, 0.675}, {4.5, 0.675}, {4.6, 0.675}, {4.7, 0.675},
...}

What special in the list is that it has some adjacent sublists with the same 2nd elements and continuous 1st element, as highlighted by the line breaks. By plotting it, we can see the abovementioned feature causes the horizontally aligned points in a step-like fashion.

ListPlot[data, Frame -> True, PlotRange -> {{0, 10}, {0, 1}}, ImageSize -> 400, PlotStyle -> {Red, Thick}]

enter image description here

What I want is a smooth "fitting" curve instead of a discrete point-plot. To this end, I tried Interpolation, but it turns out that increasing InterpolationOrder is of no help. Btw, adding an option of Method -> "Hermite" or Method -> "Spline" is useless, either. I also tried Fit[data, {1, x, x^2, x^3}, x], which turns out to be even worse.

interpdata = Interpolation[data, InterpolationOrder -> 10];
Plot[interpdata[x], {x, data[[1, 1]], data[[-1, 1]]}, Frame -> True, PlotRange -> All, ImageSize -> 400, PlotStyle -> {Red, Thick}]

enter image description here

So I want to manipulate the original data by replacing the adjacent sublists with the same 2nd element using a procedure like this:

Checking the length of the adjacent sublists with the same 2nd element and using the mean value of their 1st elements as the 1st element of a new sublist, then replacing those sublists with the resulting sublist, i.e., {mean of 1st elements, the same 2nd elem}. For example,

{1.6, 0.275}, {1.7, 0.275} => {1.65, 0.275},

{1.9, 0.375}, {2., 0.375}, {2.1, 0.375} => {2, 0.375}

{2.4, 0.475}, {2.5, 0.475}, {2.6, 0.475}, {2.7, 0.475} => {2.55,0.475}

I guess this can be achieved with SequenceSplit and the new list should give me a reasonable curve. But I have difficulty to use SequenceSplit in this case. Could anybody help me? It will be great if a certain interpolating method can be compared to the plot of the new list. Thank you!

$\endgroup$
2
$\begingroup$

Try this

v={{1.25, 0},{1.3, 0.125},{1.4, 0.175},{1.5, 0.225},{1.6, 0.275}, {1.7, 0.275},
  {1.8, 0.325},{1.9, 0.375}, {2., 0.375}, {2.1, 0.375},{2.2, 0.425}, {2.3, 0.425},
  {2.4, 0.475}, {2.5, 0.475}, {2.6, 0.475}, {2.7, 0.475},{2.8, 0.525}, {2.9, 0.525},
  {3., 0.525},{3.1, 0.575}, {3.2, 0.575}, {3.3, 0.575}, {3.4, 0.575}, {3.5, 0.575},
  {3.6, 0.625}, {3.7, 0.625}, {3.8, 0.625}, {3.9, 0.625}, {4., 0.625},{4.1, 0.675},
  {4.2, 0.675}, {4.3, 0.675}, {4.4, 0.675}, {4.5, 0.675}, {4.6, 0.675}, {4.7, 0.675}};
vs=Map[Mean,Split[v,Last[#1]==Last[#2]&]];
ListPlot[vs,Joined->True]
| improve this answer | |
$\endgroup$

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.