# Plot, extract data to a file

I need to save data that Mathematica uses inside the Plot command. The format that I would like to have is:

x1 y1
x2 y2
.....


i.e. basically, two columns, x and y (sorted, if possible) so that I can use the data for other programs.

I already played with Export and got the data enclosed in {} and tons of other information I don't need: color, axis, etc.

What is the nicest way to do what I am trying to do?

• Related: (14222) Jul 15, 2015 at 9:25

First you need to get the data from your Plot. Two methods are extraction with patterns:

data = Cases[Plot[Sin@x, {x, 0, 2 Pi}], Line[data_] :> data, -4, 1][[1]];


and EvaluationMonitor:

data =
Reap[
Plot[Sin@x, {x, 0, 2 Pi}, EvaluationMonitor :> Sow[{x, Sin@x}]]
][[2, 1]];


I prefer the first method's brevity and the fact that it can be used on existing Graphics output by Plot.

Then you just need to Export the data in the right format:

Export["file.txt", data, "Table"]


A somewhat more interesting example is saving data from a multi-line plot:

gr = Plot[{Sin@x, Cos@x, Sinc@x}, {x, 0, 2 Pi}]


The expression assigned to gr is a Graphics object which has the form:

Graphics[primitives, options]

We are interested in the data that makes up the primitives, therefore we will operate on First @ gr. We will also not restrict the Cases to find only the first match as was done above (the fourth argument of Cases).

multidat = Cases[First @ gr, Line[data_] :> data, -4];


We could then export each part to a separate file like this:

Export["file" <> IntegerString[#2] <> ".txt", #, "Table"] & ~MapIndexed~ multidat

{"file1.txt", "file2.txt", "file3.txt"}


It should be pointed out that if you do not require the adaptive sampling of Plot you can generate your data more simply and directly using Table, e.g.:

Table[{x, Sin@x}, {x, 0, 2 Pi, 0.01}]


# 3D Plots

jheidk51 asks: "How can this be generalised for 3D plots?"

This depends on the format of the plot. In the simplest case of a single formal function (one z value per x,y pair) we can just pull all the points from GraphicsComplex:

gr3D = Plot3D[x^2*Cos[y], {x, -5, 5}, {y, -5, 5}];

points = FirstCase[p3D, GraphicsComplex[p_, __] :> p, {}, -4];

ListPlot3D[points]


However in plots with multiple surfaces the points will be mixed and jumbled. They are still valid points as shown with ListPointPlot3D but attempted surface plots will be a mess.

gr3Dmulti =
ParametricPlot3D[{{4 + (3 + Cos[v]) Sin[u], 4 + (3 + Cos[v]) Cos[u],
4 + Sin[v]}, {8 + (3 + Cos[v]) Cos[u], 3 + Sin[v],
4 + (3 + Cos[v]) Sin[u]}}, {u, 0, 2 Pi}, {v, 0, 2 Pi},
PlotStyle -> {Red, Green}, Mesh -> None]


points = FirstCase[gr3Dmulti, GraphicsComplex[p_, __] :> p, {}, -4];

ListPointPlot3D[points, BoxRatios -> Automatic]


ListPlot3D[points, BoxRatios -> Automatic]


We can convert GraphicsComplex expressions to explicit coordinates using Normal, then split elements by GraphicsGroup and extract Polygon coordinates:

poly =
Cases[
Normal[gr3Dmulti],
GraphicsGroup[g_] :>
Cases[g, Polygon[p_, __] :> p, -4],
-5
];


These polygon coordinates can be used to reconstruct the plot:

Graphics3D[{EdgeForm[], Orange, Polygon @ poly[[1]], Cyan, Polygon @ poly[[2]]}]


• I had the same issue with NDSolve graph and I was looking for just 2 colums of pure numbers. This helped a lot. Thanks. Mar 24, 2013 at 13:01
• I understand the use of levelspec -4, but puzzlingly, in the example the pattern allows this to work too: Cases[First@gr, Line[data_] :> data, -1] Mar 25, 2013 at 10:47
• @Chris Don't be puzzled. I normally use -1 with such patterns, but recently I've been trying to be more specific with my level specifications which in some cases makes a significant difference in speed as fewer expressions are scanned wastefully. In this case it doesn't make a big difference. Mar 25, 2013 at 15:40
• What are exactly these values Line[data_] :> data, -4, 1][[1]]; that are shown in mathematica??i have to extract values from a plot of a pretty complicated function and these informations are very important to me..thanks in advance!
– user30749
Jul 13, 2015 at 13:22
• @jheidk51 I extended my answer to address this. Let me know if you have any problems or further questions. Jul 16, 2020 at 15:25