11
$\begingroup$

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!

$\endgroup$
5
  • $\begingroup$ What kind of plot? $\endgroup$ Nov 7, 2012 at 4:20
  • $\begingroup$ Is it a regular, two dimensional Plot? Are you looking for image-manipulation techniques? (If so, I'm out.) $\endgroup$
    – VF1
    Nov 7, 2012 at 4:26
  • $\begingroup$ 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? $\endgroup$
    – weesiang
    Nov 7, 2012 at 4:34
  • $\begingroup$ 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? $\endgroup$
    – VF1
    Nov 7, 2012 at 4:41
  • $\begingroup$ OH! yes yes it worked out! that's exactly what I was looking for! Thank you! $\endgroup$
    – weesiang
    Nov 7, 2012 at 4:48

6 Answers 6

17
$\begingroup$

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.

$\endgroup$
1
  • 2
    $\begingroup$ 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[]. $\endgroup$ Nov 7, 2012 at 5:43
15
$\begingroup$

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 = Internal`Bag[];
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; 
      Internal`StuffBag[bag, p]])],
  Dynamic[p]]

interface for point selection

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.

Internal`BagPart[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}} *)
$\endgroup$
3
  • $\begingroup$ @ 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? $\endgroup$
    – yulinlinyu
    Nov 7, 2012 at 7:51
  • $\begingroup$ @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]]. $\endgroup$ Nov 7, 2012 at 16:58
  • $\begingroup$ Sorry, I mean that how to increase the digits when I use Rightclick->Get coordinates in the Plot. $\endgroup$
    – yulinlinyu
    Nov 8, 2012 at 8:20
4
$\begingroup$

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

$\endgroup$
3
$\begingroup$

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.

$\endgroup$
1
$\begingroup$

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]

enter image description here ( 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)

enter image description here

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

enter image description here

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]

enter image description here

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – george2079
    May 20, 2013 at 20:15
0
$\begingroup$

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"])
  ]
 ]
$\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.