From: villegas@dragonfly.wri.com (Robert Villegas)
Subject: Re: extracting points from Plot[ ] (mma)?
Keywords: Plot, extract, points, Cases
Organization: Wolfram Research, Inc.
Date: Wed, 7 Oct 1992 16:41:08 GMT

In article <Oct.7.00.44.57.1992.4714@ruhets.rutgers.edu> myadav@ruhets.rutgers.edu (Mahesh Yadav) writes:
>
> Mathematica question on extracting the points which mma uses for Plotting
>-------------------------------------------------------------------------------
>
>	I am trying to extract the points { {x1,y1},{x2,y2},... } of some 
>simple function, say y=Sin[x]. Now, if I like to extract about 10 points
>which are EQUI-DISTANT in x, I can do it by the command:
>
>In[1]:= Table[N[{x,Sin[x]}],{x,0,Pi,Pi/10}]
>
>	But I am interested in the points which are "OPTIMIZED" like that in
>the Plot command. In Plot command, the function is sampled according to the 
>changes in the function -- sampling increases where the change in the function
>is greater. 
>
>	I can see the points by the command:
>
>In[2]:=  InputForm[Plot[Sin[x],{x,0,Pi},DisplayFunction->1,PlotPoints->11]
>
>		(Here DisplayFunction->1 to suppress the graphic output)
>
> but I get lot of extraneous information ( I have shown it in the end). Is 
>there a way to just get the points in the format { {x1,y1},{x2,y2}, ... }.
>

   You can store the plot data in a variable, and then use the Cases command
to search for the pattern Line[{pt1, pt2, ..., ptn}] and extract it.

In[1]:= plot = Plot[Sin[x], {x, 0, Pi}, PlotPoints->11, DisplayFunction->
          Identity] 

Out[1]= -Graphics-

In[2]:= cases = Cases[plot, Line[points_List] :> points, -1]

Out[2]= {{{0., 0.}, {0.314159, 0.309017}, {0.628319, 0.587785}, 
 
   . . . <lots of points deleted> . . .
 
>     {2.04204, 0.891007}, {2.19911, 0.809017}, {2.51327, 0.587785}, 
 
                                               -16
>     {2.82743, 0.309017}, {3.14159, 1.22461 10   }}}

In[3]:= pointslist = First[cases]

Out[3]= {{0., 0.}, {0.314159, 0.309017}, {0.628319, 0.587785}, 
 
   . . . <lots of points deleted> . . .
 
                                              -16
>    {2.82743, 0.309017}, {3.14159, 1.22461 10   }}


   If you wanted to do this often, then you could define a function that
takes its arguments like Plot does, and calls Plot, but skips the plot
and performs the Cases extraction.  You could use the DisplayFunction option
to specify that the Cases operation should be performed on the graphics
object generated by Plot.  Normally, DisplayFunction is set to a function
that converts the graphics expression -Graphics- to PostScript and sends
that to the display, but you can specify absolutely any function you want
to apply to the graphics object that is returned by Plot.

In[4]:= SamplePoints[fexpr_, {x_, x1_, x2_}, opts___] :=
          Plot[fexpr, {x, x1, x2},                  
            DisplayFunction->(Cases[#, Line[points_List] :> points, -1] &),
            opts]

In[5]:= SamplePoints[Sin[x], {x, -Pi, Pi}]

                                -16
Out[5]= {{{-3.14159, -1.22461 10   }, {-2.87979, -0.258819}, 

 . . . <lots of points deleted> . . .
 
                                                               -16
>     {2.61799, 0.5}, {2.87979, 0.258819}, {3.14159, 1.22461 10   }}}


By the way, your setting of DisplayFunction->1 tried to treat the number
'1' as a function to apply to the graphics expression.  Since '1' doesn't
perform any operation, what you got was

1[-Graphics-]

When you want to suppress the display of a graph, use the setting

DisplayFunction->Identity


Robby Villegas
Wolfram Research