4
$\begingroup$

I have an (excel) table where my first column have decimals from -3 to 3, and the other columns have associated values, in such a way that i have a "vector array" similar to this:

x1 -> {y1, y2, y3}
x2 -> {y2, y4, y5, y6}
x3 -> {y1, y5, y7}
x4 -> {y2, y8}
x3 -> {y2, y6, y7, y8, y9}

I have more than 600 "rows" or vectors. Some "x" values could be duplicated, but most of the "y" values wont, but it's possible.

How could i plot the vectors in a scatterplot? I would like to have something like this:

enter image description here

Could it be done with ListPlot?

$\endgroup$

3 Answers 3

4
$\begingroup$
data = {x1 -> {y1, y2, y3}, 
x2 -> {y2, y4, y5, y6}, 
x3 -> {y1, y5, y7}, 
x4 -> {y2, y8}, 
x3 -> {y2, y6, y7, y8, y9}};

We can change the head of each element of data to a List, then Thread each one together

Thread /@ (List @@@ data)

(*

{{{x1, y1}, {x1, y2}, {x1, y3}}, {{x2, y2}, {x2, y4}, {x2, y5}, {x2, 
   y6}}, {{x3, y1}, {x3, y5}, {x3, y7}}, {{x4, y2}, {x4, y8}}, {{x3, 
   y2}, {x3, y6}, {x3, y7}, {x3, y8}, {x3, y9}}}

*)

An example with numerical data:

SeedRandom[1001];
n = 20;
xArr = Round[RandomReal[{-3, 3}, n], 0.1];
data = # -> RandomInteger[{0, 2500}, RandomInteger[{1, 10}]] & /@ xArr;

formattedData = Thread /@ (List @@@ data);

ListPlot[formattedData, PlotRange -> All, Frame -> True, 
 GridLines -> {Range[-3, 3, 0.5], Range[0, 2500, 500]}, 
 PlotMarkers -> Graphics[{PointSize[0.03], Point[{0, 0}]}]]

enter image description here

$\endgroup$
3
$\begingroup$

If your data is in the form of

data = {x1 -> {y1, y2, y3},
  x2 -> {y2, y4, y5, y6},
  x3 -> {y1, y5, y7},
  x4 -> {y2, y8},
  x3 -> {y2, y6, y7, y8, y9}};

you can use the following code to convert it into normal points, and then use ListPlot.

Flatten[Table[
  Table[{data[[i, 1]], data[[i, 2, j]]}, {j, 1, 
    Length[data[[i, 2]]]}], {i, 1, Length[data]}], 1]

(*{{x1,y1},{x1,y2},{x1,y3},{x2,y2},{x2,y4},{x2,y5},{x2,y6},{x3,y1},{\
x3,y5},{x3,y7},{x4,y2},{x4,y8},{x3,y2},{x3,y6},{x3,y7},{x3,y8},{x3,y9}\
}*)

If you importe the Excel table directly, the data is more likely to look like this.

data = {{x1, y1, y2, y3},
   {x2, y2, y4, y5, y6},
   {x3, y1, y5, y7},
   {x4, y2, y8},
   {x3, y2, y6, y7, y8, y9}};

Then you can use

Flatten[Table[
  Table[{data[[i, 1]], data[[i, j]]}, {j, 2, Length[data[[i]]]}], {i, 
   1, Length[data]}], 1]
$\endgroup$
2
$\begingroup$

As @houzw points out, when importing the table directly from Excel, the data structure looks like this:

data = {
        {x1, y1, y2, y3},
        {x2, y2, y4, y5, y6},
        {x3, y1, y5, y7},
        {x4, y2, y8},
        {x3, y2, y6, y7, y8, y9}
       };

To get the point structure you need from the above ragged array, the following form is shorter:

Thread[{#1, {##2}}] & @@@ data// SortBy[Length] // Column[#, Spacings -> 1.5] &

enter image description here

Grabbing the @ydd's example:

SeedRandom[1001];
n = 20;
xArr = Round[RandomReal[{-3, 3}, n], 0.1];
data = {#, Splice@RandomInteger[{0, 2500}, RandomInteger[{1, 10}]]} & /@ xArr;

formattedData = Thread[{#1, {##2}}] & @@@ data;

ListPlot[formattedData, PlotRange -> All, Frame -> True, 
GridLines -> {Range[-3, 3, 0.5], Range[0, 2500, 500]}, 
PlotMarkers -> Graphics[{PointSize[0.03], Point[{0, 0}]}]]

enter image description here

$\endgroup$

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.