2
$\begingroup$

I am making plots for data, and what I get are some staircase-like plots. Data I have is usually like this, for x and y axis (data given in lists is just an example):

x={0.405, 0.41, 0.415, 0.42, 0.425, 0.43, 0.435, 0.44, 0.445, 0.45,
0.455, 0.46, 0.465, 0.47, 0.475, 0.48, 0.485, 0.49, 0.495, 0.5}

y={0.105, 0.2, 0.2, 0.2, 0.301, 0.302, 0.305, 0.306, 0.307, 0.4,
0.4, 0.4, 0.465, 0.47, 0.475, 0.48, 0.485, 0.49, 0.495, 0.5}

How can I use Mathematica to get all intervals with repeating y values with corresponding interval of x values for which these repeats happens?

$\endgroup$
1
$\begingroup$
  1. "For all pairs {xi, yi}, select those ones with the same y-value.":

    g = GatherBy[Transpose[{x, y}], Last]

    A typical entry of g looks like, eg

    {{0.41, 0.2}, {0.415, 0.2}, {0.42, 0.2}}

    (which is the second entry of g, or g[[2]], when using the example data)

  2. "For every collection of pairs with the same y-coordinate, rearrange the pairs to obtain a list similar to {{x1, x2, ..., xn}, y0}":

    (the first component of the new list contains the range of x-values and the second component is simply the common y-coordinate)

    Define f = (Transpose[#] &) /* ({#[[1]], #[[-1, 1]]} &) which simply transposes its argument (a list of pairs) and then composes a list with first entry all the x's (#[[1]]) and second entry the first of the y's (#[[-1,1]]) which is the same as the rest of the y's (because, see question).

    Below, using f along with g obtained above,

    Apply[f[{##}]&, g, 1]

    evaluates to

    { {{0.405}, 0.105}, {{0.41, 0.415, 0.42}, 0.2}, {{0.425}, 0.301}, {{0.43}, 0.302}, {{0.435}, 0.305}, {{0.44}, 0.306}, {{0.445}, 0.307}, {{0.45, 0.455, 0.46}, 0.4}, {{0.465}, 0.465}, {{0.47}, 0.47}, {{0.475}, 0.475}, {{0.48}, 0.48}, {{0.485}, 0.485}, {{0.49}, 0.49}, {{0.495}, 0.495}, {{0.5}, 0.5} }

    when we use the data from the example in the question.

In short, defining the following function:

sol[x_, y_] := Module[{g, f},
  g = GatherBy[Transpose[{x, y}], Last];
  f = (Transpose[#] &) /* ({#[[1]], #[[-1, 1]]} &);
  Apply[f[{##}] &, g, 1]
 ]

and evaluating it, using as inputs x and y (defined in the questiion) ie sol[x, y], should produce a list, where each entry is itself a list with the first component containing a range of x values and the second component containing the common y value corresponding to the range of x values.

$\endgroup$
3
$\begingroup$
KeyValueMap[{#2, #} &]@GroupBy[Transpose[{x, y}], Last -> First] 

{{{0.405}, 0.105}, {{0.41, 0.415, 0.42}, 0.2}, {{0.425},   0.301}, {{0.43}, 0.302}, {{0.435}, 0.305}, {{0.44},   0.306}, {{0.445}, 0.307}, {{0.45, 0.455, 0.46}, 0.4}, {{0.465},   0.465}, {{0.47}, 0.47}, {{0.475}, 0.475}, {{0.48}, 0.48}, {{0.485},   0.485}, {{0.49}, 0.49}, {{0.495}, 0.495}, {{0.5}, 0.5}}

$\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.