# Getting a list of accurate coordinates from a plot

I have encountered this problem of getting a list of accurate coordinates from a plot. Upon searching online, the best method of doing so is to right-click on the plot and select "Get Coordinates". After which, I will have to use my mouse to probe and move along the plot as accurately and steadily as I can, but it was rather inaccurate.

Hence, I will like to ask if there are any other methods to get the list of accurate coordinates from a plot?

Thank you!

-
What kind of plot? –  Ｊ. Ｍ. Nov 7 '12 at 4:20
Is it a regular, two dimensional Plot? Are you looking for image-manipulation techniques? (If so, I'm out.) –  VF1 Nov 7 '12 at 4:26
nope, I am not doing any image manipulation. For instance, y = x^2. After the graph is plotted, how do you get a list of coordinates of the graph? Are there any commands or something? –  weesiang Nov 7 '12 at 4:34
There is a very large number of coordinates. If you are looking for a table of values, perhaps Table[{x, x^2}, {x, 0, 4, .1}] is what you're looking for? –  VF1 Nov 7 '12 at 4:41
OH! yes yes it worked out! that's exactly what I was looking for! Thank you! –  weesiang Nov 7 '12 at 4:48

I would not suggest using Table as VF1 suggested, as it is very easy to miss critical regions because of the regular sampling that Table uses. Bumping up the sampling rate is not always a wise idea.

Instead, I suggest using EvaluationMonitor, which is an option for Plot. This allows you to make use of Plot's adaptive algorithms for the sampling and get the points that end up being plotted. For example:

With[{f = Sin@#^2 &}, Reap@Plot[f@x, {x, 0, 10}, EvaluationMonitor :> Sow@{x, f@x}]][[2, 1]]


An alternative to this would be to simply get the coordinates from the FullForm of the plot object as:

With[{fig = Plot[Sin[x^2], {x, 0, 10}]}, First@Cases[fig, Line[x_] :> x, Infinity]]


but this becomes messy to handle when you have several lines plotted at once.

-
Apart from EvaluationMonitor, you could also do something like First @ Cases[Normal[Plot[(* stuff *)]], Line[l_] :> l, Infinity] if you want the actual sampling points used. An alternative is to set the option Mesh -> All and grab the Point[] objects in the plot with Cases[]. –  Ｊ. Ｍ. Nov 7 '12 at 5:43

My impression was that you might want a point-and-click interface to select points, after generating a plot like so:

f[x_] = x^3 - x;
plot = Plot[f[x], {x, -1.3, 1.3}]


Now, the following code sets up a graphic that allows you to click and drag to get points on the graph.

p = {0, f[0]};
bag = InternalBag[];
Labeled[EventHandler[
Show[plot, Epilog -> {PointSize[Large], Red,
Point[Dynamic[{p[[1]], f[p[[1]]]}]]}],
"MouseDragged" :> (pt = MousePosition["Graphics"];
If[Abs[pt[[2]] - f[pt[[1]]]] < 0.1, p = pt;
InternalStuffBag[bag, p]])],
Dynamic[p]]


The label is dynamically updated to reflect the value of the point on the graph near the mouse position. The results are stored in the bag, which you can access as follows.

InternalBagPart[bag, All]

(* Out: {{0.618387, -0.341731}, {0.623414, -0.341731},
{0.623414, -0.330505}, {0.628442, -0.330505},
{0.633469, -0.330505}, {0.643525, -0.330505},
{0.648552, -0.330505}, {0.65358, -0.330505}} *)

-
@ Mark McClure, I'm impressed by your codes, and I'm sure your codes will help me a lot in the data analysis during my scientific research. Now I'm just wondering about how to increase the accuracy of the dynamic display when I use GetCoordinates. Any idea? –  yulinlinyu Nov 7 '12 at 7:51
@yulinlinyu Thanks - I'm glad it helps! If I understand correctly, you'd simply like more more digits displayed in the label. You could accomplish this by replacing the Dynamic[p] with Dynamic[NumberForm[p,12]]. –  Mark McClure Nov 7 '12 at 16:58
Sorry, I mean that how to increase the digits when I use Rightclick->Get coordinates in the Plot. –  yulinlinyu Nov 8 '12 at 8:20

As mentioned in the comments above, you are looking for a table of values rather than all of the values of the coordinates in a plot of your function. Look at Table in the docs for an extensive description of how to use it.

Here's an example:

Table[{x, x^2}, {x, 0, 4, .1}]


Returns a list of pairs of $(x, y)$ coordinates where $y(x) = x^2$ for $x$ values between $0$ and $4$ with a step size of $0.1$.

-

If the plot is as follows:

pl = Plot[x^2, {x, -1, 1}]


then the list out of which the plot is built takes the form:

pl[[1, 1, 3, 2, 1]]


The output is, however, very long.

-

This is my code, inspired by Mr. Mark McClure,

curve = Plot[1/(1 + 4 \[Pi]^2 x^2), {x, -2, 2}, PlotRange -> All];

DynamicModule[{p = Undefined},
EventHandler[
Show[curve, Frame -> True,
Epilog ->
Text[Style[Dynamic@p, Red, FontFamily -> "Arial", 15],
Scaled@{0.1, 0.15}, {-1, 0}]],
"MouseClicked" :> (p = MousePosition["Graphics"])
]
]

-

I'm adding a new answer here in response to this closed question: Does resizing plots produce new data?

listplot some random data..

step = 0;
ListPlot[data =
Table[  If[EvenQ[i],
step += RandomReal[]; {i 10, step} , {i 10 + 7 , step}], {i, 0,
10}], Joined -> True]


( sorry note my first plot here is not the exact same random data, and I dont feel like re-doing all the other figures..)

now graphically manipulate points (as described in the other question)

now copy/paste the modified graphic into an input cell, assigning it to some symbol.

extract the data ....

newdata = List @@ First@Cases[g, Line[__], Infinity] // First


->

{{0., 0.816202}, {17., 0.816202}, {20., 1.6845}, {37., 1.6845}, {40.,
1.7535}, {57., 1.7535}, {33.4724, 2.72161}, {77., 2.4167}, {80.,
2.86106}, {97., 2.86106}, {100., 3.34511}}

Show[{
ListPlot[data, Joined -> True , PlotStyle -> {Dashed}],
ListPlot[newdata , Joined -> True]}, PlotRange -> All]
`

-
just noticed you can do the same with "copy selection" to copy the line from the plot, which may be useful if you have a multi line plot. –  george2079 May 20 '13 at 20:15