I found that the fact is very useful that a plot sometimes contains all the original data needed to reconstruct that plot. This is very helpful for me because sometimes I need to retrieve and analysis the numerical data in plots I produced in the past. It's much easier for me(in the sense of organization of projects) to just save the plots in notebooks rather than save the numerical data in some separated files.

For example:

data1 = {{1., 2.}, {2., 3.}, {3., 1.}};
pic1 = ListPlot[data1, Joined -> True]

enter image description here

I can get the data back using

Cases[pic1, Line[x__] -> x, ∞]
(* {{{1., 2.}, {2., 3.}, {3., 1.}}} *)

This works great most of the time, but sometimes when I specified a plot range, some data are lost:

data2 = Table[{x, Cos[x]^2}, {x, -π/2, π/2, π/8}] // N;
ListPlot[data2, Joined -> True]
pic2 = ListPlot[data2, PlotRange -> {{0, 1.5}, {0, 0.5}}, Joined -> True]

enter image description here enter image description here

Graphics[Cases[pic2, _Line, ∞], AspectRatio -> 1/GoldenRatio, Axes -> True]

enter image description here

Note that the data are lost only at the vertical direction. So are there ways to tell Mathematica to save all the data into the plot?

  • 1
    $\begingroup$ You can PlotRange -> All in ListPlot and clip the graphics afterthen by Show[#, PlotRange -> {{0, 1.5}, {0, 0.5}}] &. $\endgroup$
    – Silvia
    Dec 10 '13 at 4:35

Use Show to impose PlotRange:

data2 = Table[{x, Cos[x]^2}, {x, -π/2, π/2, π/8}];
ListPlot[data2, Joined -> True]
pic2 = Show[ListPlot[data2, Joined -> True], PlotRange -> {{0, 1.5}, {0, 0.5}}]

Then this will give you everything:

Graphics[Cases[pic2, _Line, ∞], AspectRatio -> 1/GoldenRatio, Axes -> True]

Although this is not really an answer to your question, I would like to point out another simple way to make data persistent without the need for external files. This may be beneficial in the long run, because the structure of Graphics, Plots etc. may change over time (and has done so a few times already), leading to potential legacy problems.

Button together with With can store data very nicely across sessions and does not take up a lot of notebook real estate. Consider this:

data = Table[FresnelC[x], {x, 0, 3, 0.05}];
With[{data = data}, Button["data", Print[data]]]

Now you can reproduce data at leisure by pressing the relevant button even across sessions.

Mathematica graphics

Of course, once you re-evaluate the generating cell, the content will be overwritten, so you´d have to take care doing that only when desired.

Depending on your requirement, this can be built upon:

With[{data = data}, Button["data", CellPrint[TextCell[Defer[savedat = data;], "Input"]]]]

Now pressing the button will output a deferred expression you can evaluate and use with ease.

Mathematica graphics

Plus, you can style your button any old how (here, much redundant):

With[{data = data}, Button[ListLinePlot[data], 
  CellPrint[TextCell[Defer[savedat = data;], "Input"]]]]

Mathematica graphics

For large data sets, you might also want to consider using Compress at some stage. To decouple buttons from their generating cell, you could e.g. cut&paste them or do similar things programmatically, too.

  • $\begingroup$ That's really helpful!! Thanks a lot! $\endgroup$ Dec 10 '13 at 17:38
  • $\begingroup$ Glad you do not consider it OT :D I ran into some issues doing similar things when there was a change in the color handling (RGBColorvs. Hue, I think) during some prior version switch. For large sets, you should also consider using Compress additionally. $\endgroup$
    – Yves Klett
    Dec 10 '13 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.